【Head First Java】知识点:Chapter 8

 

多态(polymorphism)

  • 概念:同一个对象(事物),在不同时刻体现出来的不同状态。(编译时期状态和运行时期状态不一致的现象)
  • 前提:要有继承或者实现关系、要有方法重写、要有父类/父接口的引用指向子类对象。
  • 格式:
1、父类 变量名 = new 子类();    //普通类多态定义的格式
                          //class Fu{}
                          //class Zi extends Fu{}
                          //Fu f = new Zi();

2、抽象类 变量名 = new 抽象类子类();    //抽象类多态定义的格式
                                 //abstract class Fu {}
                                 //class Zi extends Fu {}
                                 //Fu f = new Zi ();

3、接口 变量名 = new 接口实现类();    //接口多态定义的格式
                               //interface Inter ()
                               //class AinterImpl implements Inter{}
                               //Inter i = new AinterImpl ();

4、方法的参数、返回类型、数组的类型都可以多态!!!!
  • 成员访问特点:(多态只适用于成员方法,只有在运行期间才能体现)
A:成员变量:
            编译看左边,运行看左边。(所有的成员变量取决于编译时类型!!!!)
//编译时期:参考的父类中是否有被调用的成员变量。没有,编译失败。 
//运行时期:也是调用父类中的成员变量。

B:成员方法:
            编译看左边,运行看右边。(所有的成员方法取决于运行时类型!!!!)
//编译时期:参考父类,如果父类中没有调用的方法,编译失败。
//运行时期:参考父类,优先运行子类中重写后的成员方法。子类若没有,则往父类上找。

C:构造方法:
            创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。

D:静态方法:
            编译看左边,运行看左边。(所有的静态方法取决于编译时类型!!!!)
//静态和类相关,算不上重写,所以,访问还是左边的。
  • 优缺点:提高程序的可维护性和可扩展性,但父类/接口声明的引用变量不能访问子类特有功能。(解决办法:向下转型)
  • 类型转换格式:
向上转型:
            父类 引用变量名 = new 子类(); //Fu f = new Zi ();

向下转型:
            子类 变量名 = (子类)父类引用变量; //Zi z = (Zi) f;

//注意:必须保证对象原来创建的是"猫",向下转型的时候也是"猫"!!!!
  • 使用 instanceof 关键字来判断对象是否是类的实例:
格式: boolean result = obj instanceof Class

例子: if (adog instanceof Dog){
          Dog d = (Dog) adog;
}

抽象(abstract)

  • 抽象类:就是不能使用new方法进行实例化的类,即没有具体实例对象的类。抽象类有点类似“模板”的作用,目的是根据其格式来创建和修改新的类。对象不能由抽象类直接创建,只可以通过抽象类派生出新的子类,再由其子类来创建对象。
格式: 在类的声明前面加上关键词abstract

public abstract class Animal {...}
  • 抽象方法:只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。
格式: 在方法的声明前面加上关键词abstract,然后去掉方法体(即“{}”),直接分号结束

public abstract void eat();
  • 抽象类一般包含抽象方法和普通方法。(但抽象类也可以没有抽象方法
  • 含有抽象方法的类(包括直接定义了一个抽象方法;或继承了一个抽象父类,但没有完全实现父类包含的所有抽象方法;或实现了一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类
  • 抽象类的子类必须实现父类的抽象方法。(如果一个子类没有实现父类中的抽象方法,则该子类也成为了一个抽象类!
  • 抽象类中可以包含构造方法, 但是构造方法不能被声明为抽象。
  • 抽象类的作用:在不同的类中需要不同的实现、那么这个时候就需要用到抽象类的抽象出这个抽象方法,当继承了这个抽象类的子类,就可以不同实现(这点和接口很像)。抽象类的另一个作用是各个子类都有相同的方法行为的时候,就可以在抽象类中统一实现这个方法。这个就是上面说的抽象类中的普通方法的作用了。这样在各个子类中就不需要再实现了,起到了抽象的作用。
  • abstract不能与private、static、final、native并列修饰同一个方法。
1.abstract与private一起使用,相互矛盾
abstract修饰的方法是要给子类重写,private修饰的方法只能本类访问。

2.abstract与static一起使用,无意义
abstact修饰的方法是抽象的,没有实体。而static修饰的方法,类是可以直接调用,调用抽象方法是没有意义的。

3.abstract与final一起使用,相互矛盾
final修饰方法不让子类重写,而abstract修饰的方法就是为了让子类重写。

接口(interface)

  • 概念:(官方解释)Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)(自己理解)接口可以理解为一种特殊的类,里面全部是由全局常量公共的抽象方法所组成。接口是解决Java无法使用多继承的一种手段,但是接口在实际中更多的作用是制定标准的。或者我们可以直接把接口理解为100%的抽象类,既接口中的方法必须全部是抽象方法。(JDK1.8之前可以这样理解)
  • 格式:
接口声明格式:    public interface 接口名 {
                 [public static final] 常量1;
                 [public static final] 常量2;
                        ...
                 [public abstract] 方法1; 
                 [public abstract] 方法2; 
                        ...
                 //接口中的属性是常量,即使定义的时候不添加public static final修饰符,系统也会自动添加
                 //接口中的方法只能是抽象方法,即使定义的时候不添加public abstract修饰符,系统也会自动加上
                 //注意在声明的时候要给变量赋予初值
}

实现声明格式:    public class Dog extends Canine implements 接口1,接口2,... {
                 //在这里重写接口1,接口2,...的所有方法
                        ...
}
  • 一个接口也能够拥有方法和属性,但是在接口中声明的所有方法默认是抽象的
  • 接口的子类(如果不是抽象类)必须实现接口之中的全部抽象方法。
  • 一个类可以实现一个或多个接口(支持多继承),不同继承树的类也可以实现相同的接口。
  • 直接向接口中扩展方法可能带来问题:所有实现原来接口的类将因为接口的改变而不能正常工作。(解决办法:需要通过继承扩展接口,即一个接口可以 extends 另一个接口,或者另一些接口,接口也可以继承,并且可以多继承
扩展接口格式:    public interface 接口名 extends 父接口1,父接口2,... {...}
  • 一个接口可以有多个父接口,子接口继承父接口的所有常量和方法。
  • 可以用接口作为参数或返回类型,这样就可以传入任何有实现该接口的子类。
  • 在类的继承中,只能做单重继承,而实现接口时,一次则可以实现多个接口,每个接口间使用逗号“,”分隔。这时就可能出现常量或方法名冲突的情况,解决该问题时,如果常量冲突,则需要明确指定常量的接口,这可以通过“接口名.常量”实现。如果出现方法冲突时,则只要实现一个方法就可以了。
  • 与Java的类文件一样,接口文件的文件名必须与接口名相同
  • 如果一个类实现了一个接口中要求的所有的方法,然而没有提供方法体而仅仅只有方法标识,那么这个类一定是一个抽象类。
  • 我们不能直接去实例化一个接口,因为接口中的方法都是抽象的,是没有方法体的。但是,可以使用接口类型的引用指向一个实现了该接口的对象,并且可以调用这个接口中的方法。

抽象类与接口的区别:

  • 接口是对动作的抽象,抽象类是对本质的抽象。
    抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。
    比如,男人和女人,他们的抽象类是人类,而猫和狗的抽象类是宠物类。
    人类可以吃东西,宠物类也可以吃东西,但是两者不能混为一谈,因为有本质的区别。
    这个“吃东西”是一个动作,你可以把“吃东西”定义成一个接口,然后让两个类去实现它的方法。

    一个类只能继承一个类或抽象类,正如人不可能同时是动物类又是植物类,但是可以实现多个接口,例如,吃饭接口、呼吸接口等。
  • 抽象类可以有具体的方法和属性,  接口只能有抽象方法和不可变常量(final)。
  • 抽象类主要用来抽象类别,接口主要用来抽象功能。
  • 抽象类实现接口时,接口的方法在抽象类中可以被实现也可以不被实现,而普通实现接口必须实现所有接口方法。
  • 当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值