Java语言:多态(未完)

目录

多态的概念

向上转型

向下转型

instanceof运算符

类型的转换的案例

抽象类

抽象方法

接口

接口成员====抽象方法和常量

接口成员===静态方法和默认方法

关于多接口重名默认方法处理的解决方案

关于多接口重名常量处理的解决办法

接口的继承


多态的概念

多态意味着允许不同类的对象对同一消息做出不同的响应

多态分为

Java语言:多态(未完)_第1张图片

运行时多态

Java语言:多态(未完)_第2张图片

Java语言:多态(未完)_第3张图片

向上转型

对于父类引用指向子类对象,这里就要涉及到向上转型和向下转型,这里先讲向上转型

所谓向上转型就是父类引用指向子类对象实例,向上转型也称为隐式转型或者是自动转型,可以这样理解,子类对象实例向上转型为父类对象,这是理所当然的,所以称为自动转型,因为子类对象本来就携带了一些父类的特征

向上转型要注意的地方:父类引用指向子类对象实例之后,该引用可以调用从父类继承下来的方法和子类重写父类之后的方法,但是无法调用子类特有的方法

向上转型举例如下

//向上转型举例
//假设Animal是父类,Dog是子类
Animal one=new Dog();//这一条语句就是向上转型,父类引用指向子类实例

向下转型

向下转型又称为强制转型,就是使用子类实例指向父类引用

可以这样理解,按照常规而言,一般是说孩子长的像父亲,没有说父亲长的像孩子的,所以子类引用指向父类对象实例需要进行强制类型转换

但是向下转型不是随便就可以进行的,向下转型需要满足某些条件,才能够进行向下转型

//这里假设Animal是父类,Cat是子类,Dog也是子类
Animal one=new Cat();//向上转型
Cat two=(Cat)one;//这样就是向下转型,因为原来one就是指向Cat这个类的实例对象
Dog three=(Dog)one;//这样就是不被允许的,因为之前one是指向Cat类的,并不是指向Dog类的对象实例

如果按照Dog类那一条语句那样写,就会爆出异常ClassCastException

instanceof运算符

Java语言:多态(未完)_第4张图片

instanceof可以用于防止在向下转型的过程中出现异常ClassCastException,因为instanceof可以判断左边的对象是否拥有右边类的响应特征,如果具有右边的类的响应的特征,那么就可以进行向下转型

类型的转换的案例

Java语言:多态(未完)_第5张图片

其实上图中的写法都是可以的,没有说谁更好,至少以我现在的水平看不出来,应该根据具体的场景具体使用吧!

抽象类

抽象类主要是将具有相同特征的行为方式抽象出来,形成一种规范(个人理解)

比如你要写一个Person类,那么肯定里头要包含睡觉或者吃饭,或者一些人必备的动作,但是当你写多了,可能就会忘记这些,所以可以起到提醒的作用

对于某一类的事物,如果继承了抽象类,那么就要实现抽象类中的方法,这样也可以提醒程序员有哪些必须要写的方法,防止遗漏

还可以防止一些没有意义的类的出现

举例如下图(这里的Animal就是抽象类了,访问修饰符public和abstract可以互换位置,但是不能够和class互换位置,不过应该也没有人喜欢把abstract写在class后面吧!过于奇葩)

Java语言:多态(未完)_第6张图片

Java语言:多态(未完)_第7张图片

抽象方法

抽象方法所属的类叫做抽象类,但是抽象类中不一定要含有抽象方法。

对于抽象方法,子类一定要进行重写,如果不进行重写,那么就要将该类写成抽象类

抽象方法的写法如下

public abstract void eat();//抽象方法

还有一点static、final、private不能与abstract并存

接口

在Java中不支持多继承的机制,如果对于一些具有相同行为特征,但是不属于同一类事物的时候,这样就没有办法将它们联系起来,这时候如果使用接口,那么就可以将它们进行联系起来

个人对于接口的理解就是接口类似于抽象类,但是又不同于抽象类

接口的命名一般使用大写的I开头(如下)

Java语言:多态(未完)_第8张图片

实现接口使用implements关键字(如下)

Java语言:多态(未完)_第9张图片

并且在继承的同时还可以实现接口,还可以同时实现多接口,使用逗号隔开即可

使用接口的引用指向实现类的时候,只能够调用接口中实现了的方法,不能够调用实现类中独有的方法

  • 接口成员====抽象方法和常量

Java语言:多态(未完)_第10张图片

接口访问修饰符是:public和默认

对于抽象方法而言,访问修饰符是public,可以不写abstract

如果你使用了implements关键字,但是不想实现接口,或者是只想实现接口中的一个方法,那么可以将该类变成抽象类,这样就好了,其实这个类似于抽象类和抽象方法的使用方法

常量的使用方法(对于接口中的常量一定要进行初始化,否则会报错)

使用接口名加常量名或者是接口的引用名加常量名

比如下面这样

如果在实现类中有一个和接口中同名的常量,那么使用接口的引用调用常量的时候,调用的依然是接口中的常量;如果使用的是实现类的引用,那么调用的就是实现类中的常量,其实这也体现了Java语言的多态性

  • 接口成员===静态方法和默认方法

对于实现类而言,如果你只是想要实现接口中的一些方法,而不是全部方法,但是又不想不变抽象类,那么就可以将相应的方法(就是你不想实现的方法)变成默认方法

对于默认方法时JDK1.8之后提供的,所以老版本的JDK可能不会支持这个功能

默认方法和静态方法举例如下

Java语言:多态(未完)_第11张图片

静态方法的使用和之前的静态成员的使用有一点像,只能使用接口名的方式进行调用,不能使用接口的引用进行调用

接口中静态方法不能重写,但是对于默认方法是可以进行重写

  • 关于多接口重名默认方法处理的解决方案

解决方案就是:自己重写一下默认方法,然后无论使用哪一个接口引用调用默认方法的时候,都是调用的是实现类重写之后的默认方法

如果子类的父类和实现的接口中的默认方法同名,如果子类没有写自己的默认方法,那么调用的就是父类同名的那个方法,如果子类重写了默认方法,那么调用的就是子类中重写的那个默认方法

  • 关于多接口重名常量处理的解决办法

这个解决也是一句话,自己重新定义一个常量,这样就好了,不过个人觉得没有人会这么写代码吧?命名相同的名字?

  • 接口的继承

在Java语言中,对于类而言是不可以进行多继承的,但是对于接口而言却是可以进行多继承的,多继承的时候要使用逗号将各个接口进行分隔开。

但是实现类要将继承下来的接口中的方法都要实现,如果在两个父类接口中具有相同的方法时,那么解决冲突的办法就是自己重写一个同名方法

Java语言:多态(未完)_第12张图片

下面这张图中的情况类似于向上转型,Test类相当于是子类,a和b相当于父类引用,那么他们指的肯定是父类中的TEMP

Java语言:多态(未完)_第13张图片

 

 

 

你可能感兴趣的:(JAVA基础)