Java基础-多态&抽象类&接口

来源:互联网 发布:苹果 office 类似软件 编辑:程序博客网 时间:2024/06/05 06:13


面向对象的三大特性之三:

封装、继承、多态


一、多态的概述和前提:

概述:对象在不同时刻表现出来的不同状态。

前提:

A:要有继承

B:要有方法重写

C:要有父类引用指向子类对象


二、多态中成员的特点:

成员变量:无论编译还是运行,都是看左边,即引用型变量所属的类中是否有该方法,有则执行

非静态成员方法:

编译时:看左边,即引用型变量所属的类中是否有该方法,有则编译通过,否则编译失败。

运行时:看右边,即引用型变量所指向的子类中是否有该方法,有则调用,否则调用父类中的该方法。

静态成员方法:

无论编译还是运行,都看左边,即引用型变量所属的类中是否有该方法,有则编译通过并执行,否则编译失败。

重点掌握:非静态成员方法的特点;

编译失败的代码:

<span style="font-size:18px;">//父类class Fu{public void method(){System.out.println("Fu method!");}}//子类class Zi extends Fu{//重写父类中的method方法public void method(){System.out.println("Zi method!");}//子类中特有的方法functionpublic void function(){System.out.println("Zi function");}}public class Test {public static void main(String[] args) {// 多态Fu f = new Zi();f.function();}}</span>

IDE编译提示:


说明,在父类中没有定义function方法,在编译时期就会被检测出来,符合编译时期,看左边,即引用型变量所属的类中,是否有该被调用的方法,没有则报错。


正确的代码:

<span style="font-size:18px;">//父类class Fu{public void method(){System.out.println("Fu method!");}}//子类class Zi extends Fu{//重写父类中的method方法public void method(){System.out.println("Zi method!");}//子类中特有的方法functionpublic void function(){System.out.println("Zi function");}}public class Test {public static void main(String[] args) {// 多态Fu f = new Zi();</span>
<span style="font-size:18px;"><span style="white-space:pre"></span>//调用的是子类中重写父类的method方法f.method();}}</span>

结果:



打印的是子类中重写父类的方法method中的输出语句中的内容。和 特点中的,运行时期,看右边,即引用型变量所指向的子类中方法。



三、多态的弊端及解决方案:

弊端:父类引用无法使用子类中特有的功能。(上面的例子,就说明了这一点)

解决方案:可以将父类引用向下转型成子类类型。

上面例子出现的问题,解决方案代码如下:




四、引用类型的转型

1、向上转型:由小到大,由子类到父类;  格式:Fu f = (Fu)z ;

2、向下转型:由大到小,由父类到子类;  格式:Zi z = (Zi)f ;

多态中,引用类型转型可能会出现 java.lang.ClassCastException(类型转换异常)

出现原因:相互转换的两个类之间没有继承或者实现关系;


代码如下:

<span style="font-size:18px;">//父类class Animal {public void run() {System.out.println("just run");}}// 子类Dog继承Animal类class Dog extends Animal {public void run() {System.out.println("wangwang run");}}// 子类Cat继承Animal类class Cat extends Animal {public void run() {System.out.println("miaomioa run");}public void eat() {System.out.println("吃鱼");}}public class Test {public static void main(String[] args) {// 多态Animal a = new Dog(); // 向上转型,子类转成父类a.run(); // 打印的是Dog类中的run方法// 给a引用类型变量重新赋值a = new Cat(); // 向上转型,将子类转成父类a.run(); // 打印的是Cat类中的run方法Cat c = (Cat) a; // 向下转型 ,父类转子类c.run();// 可以调用Cat类中的特有方法eat()c.eat();// 那么这时,再将a引用向下转型为Dog是否可以呢?Dog d = (Dog) a;d.run();}}</span>

结果:


这时,会报错:ClassCastException(类类型转换异常)

是因为,程序在这里    

<span style="font-size:18px;">Cat c = (Cat) a; // 向下转型 ,父类转子类</span>
<span style="font-size:18px;">    就已经将a引用转换成Cat的类型,如果要将Cat类型的变量,转换成Dog类型,就会报这个类类型转换异常的错误。</span>
</pre><pre name="code" class="java"><span style="font-size:18px;">究其原因,就是Cat类和Dog类之间没有继承或者实现关系。</span>


五、多态的好处

多态的出现,提高了代码的扩展性和可维护性。


六、抽象类的特点;

抽象类的概述:类用abstract修饰

抽象方法:方法声明要用abstract修饰,并且没有方法体。

特点:

A:抽象类不能实例化,也就是不能创建本类对象;

B:子类继承抽象类

1、要么子类实现抽象类中的所有抽象方法

2、要么将子类也定义成抽象类;

C:抽象类的作用:强制子类实现某些功能。

注意:有抽象方法的类,一定是抽象类;但是抽象类中可以没有抽象方法。


七、抽象类中成员的特点:

A:成员变量:可以有变量,也可以有常量

B:成员方法:有抽象方法,也有非抽象方法

抽象方法的作用:强制子类实现某些功能

非抽象方法的作用:提高代码的复用性,让子类继承

C:构造方法:有构造方法

 问题:抽象类不能实例化,构造方法有什么用途?

构造方法的作用是初始化父类中的成员,以便给子类使用。


八、抽象关键字abstract不能和哪些关键字共存?

final:被final修饰的方法,不能被重写,而抽象方法最终是要被子类重写的;

private:被private修饰的方法,在子类中是无法访问的,因此子类无法重写private修饰的方法

static:被static修饰的方法,是静态的方法,随着类的加载而加载,可以使用类名去调用静态的方法,但是如果用abstract修饰静态方法,该方法也没有方法体,用类名调用该方法,没有意义。


九、接口的基本特点:

A:接口不能被实例化

B:接口中的所有方法都是抽象方法,子类要实现接口,必须重写接口中的所有抽象方法。


十、接口中成员的特点:

A:成员变量:接口中只有常量。

因为在接口中定义变量,默认有public static final修饰

B:构造方法:接口中没有构造方法。

因为在接口中,只有静态常量,随着类的加载就已经初始化完毕,并且接口中的方法都是抽象的方法,没有方法体。

C:成员方法:接口中只有抽象方法。

因为在接口中定义方法,默认有public abstract修饰。


十一、类与接口关系

1、类与类的关系:继承关系,只能单继承,不能多继承,但是支持多层继承

代码:

public class A {}class B extends A{}class C extends B{}

2、类与接口的关系:实现关系。可以单实现,也可以多实现;并且,一个类可以在继承另一个类的同时实现一个或者多个接口。

代码:

 interface A {}interface B {}class C {}class D extends C implements A,B{}

3、接口与接口的关系:继承关系。可以单继承,也可以多继承。

代码:

 interface A {}interface B {}interface C extends A,B{}


4、类与抽象类的关系:继承关系。只能单继承,不能多继承,但是支持多层继承

代码:

abstract class A{}class B extends A{}

注意:在Java的类中,不支持多继承,但是在Java中是支持多继承的,体现在接口与接口之间可以多继承。

十二、接口思想的特点:

 1、接口思想是对外暴露规则

2、接口思想是对外提供扩展功能

3、接口降低了程序的耦合性

4、接口可以用来多实现



十三、抽象类和接口的区别:

成员的区别:

抽象类中的成员

A:成员变量:可以是变量和常量

B:成员方法:可以有抽象方法,也可以有非抽象方法

C:构造函数:有构造函数。虽然不能实例化,但是用来初始化成员,共子类使用

接口中的成员

A:成员变量:只有常量,因为默认有public static final修饰

B:成员方法:只有抽象方法,因为默认有public abstract修饰

C:构造方法:没有构造方法。因为不需要初始化成员。

关系区别:

类与抽象类的关系:继承关系,只可以单继承,不可以多继承,支持多层继承

类与接口的关系:实现关系,可以单实现,也可以多实现,支持在继承一个类的同时,实现一个或多个接口。

定义区别:

抽象类:抽象类中定义的都是该体系中共性的内容

接口:接口中定义的都是该体系的扩展功能。











0 0
原创粉丝点击