系列文章目录
Java继承与组合
你知道为什么会划分数据类型吗?—JAVA数据类型与变量
10 > 20 && 10 / 0 == 0等于串联小灯泡?—JAVA运算符
你真的知道怎样用java敲出Hello World吗?—初识JAVA
目录
1.多态
1.1为什么会有多态
现实生活中,但我们完成某一个同样的行为,当不同的对象去完成时会产生出不同的状态.比如说吃食物,当猫去完成时就是吃猫粮,狗去完成时就是吃狗粮.可以概括为:同一件事情,发生在不同对象身上,就会产生不同的结果.
又比如说,当我们要打印一张资料,如果用黑白打印机那么就会打印黑白效果,彩色打印机就会打印彩色效果.
综上,我们可以引出多态的概念.
1.2 多态的概念
多态的概念:多种形态,完成某个行为,当不同的对象去完成时会产生出不同 的状态。
多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法。
1.3 重写
1.3.1 什么是重写
要学多态必须先知道什么是重写,重写是多态的基础.
若干年前的手机,只能打电话,发短信,而今天的手机,不仅仅可以打电话发短信还可以玩游戏打视频等等.在这个过程当中,我们不应该在原来老的类上进行修改,因为原来的类,可能还在有用户使用,正确做法是:新建一个新手机的类,对手机功能这个方法重写就好了,这样就达到了我们当今的需求了。
我们可以引出重写的概念,如下:
重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程 进行重新编写,返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定 于自己的行为。也就是说子类能够根据需要实现父类的方法。
所以说,对于已经投入使用的类,尽量不要进行修改。最好的方式是:重新定义一个新的类,来重复利用其中共性的内容,并且添加或者改动新的内容。
所以重写的意义便是:在不修改已经投入使用的类的情况下定义一个既有原来类的共性又有新功能的类.
1.3.2方法重写的规则:
-
子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 参数列表 要完全一致 ,方法体重新写. (注意:参数列表一致是指参数个数,参数顺序,参数类型都完全一样)
-
针对上一条规则有一个特例就是协变类型.协变类型中,被重写的方法返回值类型可以不同,但是必须是具有父子关系的.《Java编程思想》中就有这个概念.我们可以用以下代码举例,如下:
-
子类访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected
-
父类被static(被static修饰的方法不是对象的而是类的)、private修饰的方法、构造方法都不能被重写。
-
重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写
1.3.3 不能进行重写的情况
- 被private修饰的方法不能重写
- 被static修饰的方法不能重写
- 子类的访问修饰限定符小于父类的访问修饰限定符
- 被final修饰的方法 不能被重写(密封方法)
- 构造方法不能重写
1.4 重写和重载的区别
方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现
我们举一个例子,代码代码如下图:
1.5 多态实现条件
在java中要实现多态,必须要满足如下几个条件,缺一不可:
- 必须在继承体系下
- 子类必须要对父类中方法进行重写
- 通过父类的引用调用重写的方法
下面这个例子很好的说明了重写是多态的基础、重写实现多态:
class Animal {
String name;
int age;
public Animal(String name, int age){
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(name + "干饭");
}
}
class Cat extends Animal{
public Cat(String name, int age){
super(name, age);
}
@Override
public void eat(){
System.out.println(name+"吃鱼~~~");
}
public void miao(){
System.out.println(name+"喵喵喵")
}
class Dog extends Animal {
public Dog(String name, int age){
super(name, age);
}
@Override
public void eat(){
System.out.println(name+"吃骨头~~~");
}
public void bar