黑马程序员:java基础知识(二)
来源:互联网 发布:淘宝怎么关闭私人定制 编辑:程序博客网 时间:2024/04/28 16:53
---------------------- 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
0 0
- 黑马程序员:java基础知识(二)
- 【黑马程序员】Java基础知识(二)
- 黑马程序员--------Java基础知识总结(二)
- 黑马程序员--java基础知识之面向对象(二)
- 黑马程序员---java基础知识之面向对象(二)
- 黑马程序员---java基础知识(二):常量、变量、语句
- 黑马程序员——Java语言基础知识(二)
- 黑马程序员 java概述与基础知识<二>
- 黑马程序员,Java基础知识总结二
- 黑马程序员-C#基础知识(二)
- 黑马程序员-C#基础知识(二)
- 黑马程序员 java 基础知识
- 黑马程序员---- java基础知识
- 黑马程序员 Java基础知识
- 黑马程序员-----JAVA基础知识
- 黑马程序员---Java基础知识
- 黑马程序员---java基础知识
- 黑马程序员 Java基础知识
- Android 4.4 蓝牙解析(一)
- 【18】替换空格
- LRU Cache
- 字符串函数
- [leetcode] Reverse Nodes in k-Group
- 黑马程序员:java基础知识(二)
- 时光轴
- 关于||和&&的一个有趣问题
- subsys_initcall
- Android输入法框架系统(上)
- IOS_网络请求_get+post+同步+异步
- android -- 蓝牙 bluetooth (一) 入门
- 多边形背景生成工具推荐-Trianglify
- HDU 最短路小小结(只涉及初级算法)