第四章(3)、面向对象-多态、抽象类和接口

一、多态

        同一个事物(对象),在不同时刻的表现形式称为多态,比如水,在不同的时刻会呈现固态、液态、气态 。在java中,比如我有一个Dog(狗)类,那么它可以是自己的类型(狗可以是狗的类型)Dog d = new Dog(),狗又是属于动物,那么狗也属于动物类型 动物 d = new Dog()。那么什么时候才能使用多态呢?

前提和体现:

1)有继承关系(狗类可以继承动物类)

2)有方法重写

3)父类的引用指向子类对象(动物 d = new Dog()    d就是父类的引用,new Dog()就是子类对象)

多态中访问成员的特点:

1)成员方法:编译(执行javac命令的时候)看左右,运行(执行java命令的时候)看右边。

     例如:动物 d = new Dog()  左边就是父类,编译时候看看父类中是否存在这个方法,如果不存在就保存;右边是子类对象,运行的结果就是子类中的(因为有方法重写)

2)成员变量:编译看左边,运行也是看左边。意思就是不管是编译时期,还是运行时期,成员变量访问的都是父类中的。

3)静态方法(static修饰的方法):编译看左边,运行也是看左边。

代码如下:

        从以上结果可以看出,验证了前面所述的几个特点,多态的好处有:1)提高了代码的维护性(由继承保证);2)提高了代码的扩展性(由多态保证)。但是我们通过父类的引用去访问只有子类中有的成员(成员变量和成员方法)时,却报了找不到符号这个错,这就是多态的弊端:不能使用子类中特有的成员。如果使用了多态后,又想访问子类中的成员时,该怎么做呢?这时候就可以使用向下转型了,父类的引用指向子类对象(Father f = new Son())属于向上转型,向下转型:子类名 子类引用名 = (子类名) 父类引用名 ,

例如:(Son s = (Son)f)。

代码如下:

二、抽象类

        在之前写的代码中,不过这个类的方法是否有明确的功能,我们都给出了具体的实现,但是有一些类是比较宽泛和抽象的,并不是具体的描述某个事物,在这样的类里面去写具体的实现显然是有些不合理的,例如动物类,这个类就是很抽象,并没有指明是某个具体的动物,所以这个类中的功能不要具体的体现,而是只需要给出一个声明就行了。

        抽象方法的定义:使用abstract关键字修饰的类就称为抽象类,格式:abstract class 类名 {} (abstract  class  Animal{})。特点:1)在抽象类中不一定要有抽象方法(abstract void method(){});2)有抽象方法的类一定是抽象类;3)抽象类中有构造方法,到时不能实例化(就是不能直接new),构造方法用来实例化该类中的数据。

        抽象类的子类可以是抽象类(格式:访问权限修饰符 abstract 返回值类型 方法名();),也可以是具体的类(但必须重写父类中的所有抽象方法);抽象类中可以有变量,也可以有常量。

代码如下:

        创建抽象类的对象可以通过多态的方式去创建,在使用子类特有的功能时,向下转型成子类对象,然后再去访问。注意:abstract关键字不能和private、final关键字共存,因为抽象方法是需要被重写的,但是private或者final修饰的方法是不能被子类重写的,冲突了。

三、接口

        接口是用来做扩展功能使用的,就像电脑中的usb接口一样,是拿来连接外部的设备(扩展)的,在java中接口也是用来做一些功能的扩展的,比如人类,人都有吃和睡的功能,一般这两个功能都是抽象的,因为不同区域的人吃的东西也是不同的,但是并不是每个人都会打球,是一部分人额外的功能,就不宜把这个打球的方法放在人这个抽象类中,而是定义一个接口,并且球类运动是有许多种的,所以这个打球的方法也是抽象的。接口使用interface关键字修饰,格式:interface 接口名 {},注意是没有class的。

        抽象类实现接口(abstract class 类名 implements 接口名 {}),可以不重写接口中的抽象方法;非抽象类实现接口(class 类名 implements 接口名 {}),必须实现接口中的抽象方法。也可以多实现(class 类名 implements 接口名1,接口名2,...,接口名n {})。

接口的特点:

1)接口不能实例化(不能直接new,而是通过它的具体实现类(非抽象子类)去创建,也是多态的一种体现);

2)接口的子类可以是抽象类,也可以是非抽象类;

3)接口可以是单继承(interface 子接口名 extends 父接口),也可以是多继承(interface 子接口名 extends 父接口1,父接口2,...,父接口n),使用 , 隔开。

4)接口中没有变量,只能是常量且是静态的(public static final)。在jdk8之前,接口中只能有抽象方法(public abstract 返回值类型 方法名 ();)public abstract可以省略,但是从jdk8开始,接口中是可以有default关键字修饰的非抽象方法(只能通过实现类的对象去调用),也可以有static修饰的静态方法(只能通过接口名去调用,格式:接口名.方法名),

jdk7及其更低版本的写法。代码如下:

jdk8及以上的 (注意:你的电脑上安装配置的jdk是1.8版本及以上的才能使用以下的代码),代码如下:

抽象类和接口在设计上的区别:抽象类有共性功能,是被继承的,是“is a”关系,;接口扩展功能,是被实现的,是“like a”关系。

公众号二维码

猜你喜欢

转载自blog.csdn.net/itmzz/article/details/86566366