概述
---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------
三、接口接口,是一个特殊的抽象类。定义接口的关键字——interface。
接口中常见的定义:①常量"static final";②抽象方法 "abstract 方法();"
接口中不可以创建对象,因为在接口中有抽象方法。当一个子类实现一个接口时,必须实现了该接口的所有方法以后才能创建对象,否则这个子类还是一个抽象类,不可实例化。
在java中,不支持多继承,但子类可以实现等多个接口。相对于类,接口有一个特殊,就是接口与接口之间可以实现多继承,并且只有接口才可以实现多继承。
例如:
class CA{}
class CB{}
class CC extends CA,CB{} //这种做法是错的,java不支持多继承。
Interface IA{}
Interface IB{}
Interface IC extends IA,IB{} //这是正确的,接口可以继承多个接口。
接口的特点:
①接口是对外暴露的规则。比如计算机的主板,它定义了一种规则,只要符合它的规则的产品就可以插到主板上使用。
②接口是程序功能的扩展;
③接口可以用来多实现;
④类与接口之间是实现关系,并且一个类在继承一个类的基础上,可以实现多个接口;
⑤接口与接口之间可以有继承关系,并且可以多继承;
⑥接口降低了耦合性。
四、多态
所谓多态,就是事物存在的多种形态。比如,猫就有两种形态,一个是猫,一个是动物。
1、多态的基本体现:父类的引用指向了子类的对象,父类的引用可以接收子类对象。例:interface IA{}
class CA implements IA{}
....
IA ia = new CA(); //父类的引用指向子类对象,这就是多态的基本体现。
2、多态的前提:类与类之间,必须有从属关系,可以是继承,也可以使实现。
3、多态的好处:使用多态可以大大的提高了程序的扩展性。
4、多态的弊端:父类的引用只能访问父类中既有的成员。也就是说,在子类中扩展的新成员,使用父类引用是访问不到的。
5、类型转换:
类型转换分为向上转型和向下转型。向上转型,也叫做类型提升,就是子类类型转换成父类类型。类似于,char型转换为int型,可以隐式转换。向下转型,就是将父类类型转换为子类类型。类似于,int型转换为char型,需要进行强制类型转换。
在使用多态时,父类的引用不能访问子类的中特有的成员,所以我们往往需要将父类的引用转换成子类类型。例如:
Super sp = new Sub();//父类引用指向子类对象
Sub sb = (Sub)sp;//将父类引用转换成子类类型
在进行强制类型转换时,切记不能将父类的对象转换成子类类型。多态中,自始至终都是子类对象在做变化。例如:
Super sp = new Super();
Sub sb = (Sub)sp;//这种做法将会出现类型转换异常:ClassCastException
//在进行类型转换时,下面这种情况也会出现类型转换异常.
class Super{}
class Sub1 extends Super{}
class Sub2 extends Super{}
……
Super sp = new Sub1();
Sub2 sb2 = (Sub2)sp;//这种类型转换也会出现类型转换异常。
这是什么原因呢?可以这么解释一下,猫和狗都属于动物,想让一只猫强制转换成一条狗,当然是不行的。
那怎样避免出现类型转换异常呢?java中提供了一个关键字——instanceof。该关键字用来判断一个引用变量是否属于某个类型。沿用上面的例子:
Super sp = new Sub1();//父类引用指向了子类Sub1的实例对象
“sp instanceof Sub1” //这个判断将返回true
“sp instanceof Sub2” //这个判断将返回false
所以在使用强制类型转换时,我们可以利用instanceof来判断引用的类型,避免类型转换异常。即:
if(sp instanceof Sub1){
Sub1 s1 = (Sub1)sp;
}else if(sp instanceof Sub2){
Sub2 s2 = (Sub2)sp;
}
6、多态中成员的特点:
①非静态成员函数:在编译时期参照引用变量所属类的成员函数,在运行时期参照所创建的对象的成员函数。举例说明:
class Super{
void print1(){System.out.print("super")}
}
class Sub extends Super{
void print1(){System.out.print("sub1")}
void print2(){System.out.print("sub2")}
}
……
Super sp = new Sub();
sp.print1();//编译正常通过,因为Super类中有print1这个方法,此处输出的结果是“sub1”,因为print1()方法已经被子类覆盖。
sp.print2();//编译不通过,因为Super类中没有print2这个方法。
所以,成员函数在多态中,编译时看左边,运行时看右边。
②成员变量:无论是在编译时还是运行时,都参照引用变量所属的类(左边)。
③静态成员:无论是在编译时还是运行时,都参照引用变量所属的类(左边)。
五、内部类
1、内部类的访问规则:
①内部类可以直接访问外部类的成员,包括私有成员。之所以可以直接访问,是因为内部类中持有了一个外部类的引用:Outer.this
②外部类访问内部类,须要创建内部类的对象。
内部类对象的创建:Outer.Inner io = new Outer().new Inner();
内部类是外部类的成员,与普通的成员,可以使用成员修饰符修饰。例如,static、final等。
2、静态内部类:
静态内部类对象的创建:Outer.Inner io = new Outer.Inner().
外部类中访问内部类的非静态成员的方式:new Outer.Inner().非静态成员
外部类中访问内部类的静态成员的方式:Outer.Inner.静态成员
需要注意的是,①如果内部类中定义了静态成员,则该内部类必须是静态的;②外部类的静态方法不能访问非静态的内部类;③外部类的静态方法可以直接访问静态的内部类。例如:
class Outer{
static void function(){
Inner.show();//错误的方式
new Inner().show();//这也是错的
new Outer().new Inner().show();//这也是正确的,上面②的说法是错的?但老师是这么说的。
}
class Inner{
void show(){}
}
}
3、局部内部类:
类似于局部变量,定义在方法或代码块中。局部内部类不能是静态的;不可以被成员修饰符修饰;他仍然可以直接访问外部类的成员,因为它仍然持有外部类的引用;可以访问该局部中被final修饰的变量,没有被final修饰的变量该内部类不能访问。例:
class Outer{
void function(){
int x = 1; //没有final修饰符
final int y = 2; //有final修饰符
class Inner{
void show(){
System.out.println(x); //不可以访问
System.out.println(y); //可以访问
}
}
}
}
4、什么时候使用内部类?
类是对事物的描述,所以当某个事物内部还有事物时,我们就使用内部类来描述。例如,人体是一个事物,也就是一个类,人体内部还有心脏之类的事物,这是人体这一事物的内部事物,所以心脏这一事物就使用内部类来描述。就说,人体是外部类,心脏是内部类。
5、匿名内部类
顾名思义,就是没有名字的内部类,是内部类的简写格式。定义一个匿名内部类的前提是,该内部类必须有父类,可以是继承一个类或实现一个接口。
匿名内部类的定义格式:new 父类或接口(){ 定义子类内容 }; 。其实就是创建了父类或接口的匿名子类对象,而且是一个“带内容”的对象。
例:
interface Super{
void show1();
void show2();
}
class Outer{
//方式一:
void function1(){
new Super(){
public void show1(){
System.out.println("show1");
}
public void show2(){
System.out.println("show2");
}
}.show1();//创建了一个匿名内部类,并调用的内部类的方法show1
}
//方式二:
void function2(){
Super sp = new Super(){
public void show1(){
System.out.println("show1");
}
public void show2(){
System.out.println("show2");
}
};//创建了一个匿名内部类,并创建一个接口的引用指向这个匿名内部类。
sp.show1();
sp.show2();
}
}
上面的两种匿名内部类的创建方式中,方式二更为灵活。从方式二中,我们可以看出,匿名内部类的使用,也是多态的一种体现。但不管哪种方式,内部类必须全部实现父类或接口的抽象方法,因为内部类不能是抽象类。如果父类中的抽象方法太多,那么创建匿名内部类时,就显得很臃肿。所以,当父类或接口中的抽象方法太多时,不建议使用匿名内部类。使用匿名内部类时,内部类中定义的方法最好不要超过3个。
---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net
最后
以上就是整齐画板为你收集整理的黑马程序员:java基础知识(二)的全部内容,希望文章能够帮你解决黑马程序员:java基础知识(二)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复