目录
1、多态概念
字面:多种形态;
具体是 不同对象调用 同一个方法 产生不同的效果,方法实现了重写是多态的基础;
当父类引用 引用的对象 不一样的时候 , 行为的表现不同
2、 多态的前提与实现
前提:
- 必须在继承关系下
- 子类必须要对父类中方法进行重写
- 通过父类的引用或接口调用子类重写的方法
体现:
在代码运行时,当传递不同对象时,会调用对应类中的方法
属性看声明(属性没有多态性),方法看对象
class Animal{
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
//System.out.println("Animal 2个参构造");
}
public void eat(){
System.out.println(name + "吃东西");
}
}
class Dog extends Animal{
public String move;
public Dog(String name, int age) {
//子类构造 需要先实现 父类构造
super(name, age);
}
//方法的重写
@Override
public void eat(){
System.out.println(name + "吃骨头");
}
//特有方法
public void wangwang(){
//super.eat();
System.out.println(name + "旺旺叫");
}
}
// 二哈吃骨头
多态的优缺点
优点:
- 能够降低代码的 "圈复杂度", 避免使用大量的 if - else(向上转型)
- 可扩展能力更强,(方法的重写)
缺点:代码的运行效率降低
- 属性没有多态性
- 构造方法没有多态性
3、重写
重写:也称为 覆盖
主要 可以在子类实现复合自己特征的 方法
注意:
- private 修饰的方法不能重写(私有)
- static 修饰的方法不能重写(属于类)
- 子类的访问限定权限 要大于等于父类的权限
private < 默认 < protected < public
- 被 final 修饰的方法 能被重写,这个方法 称为密封方法(独一条)
- 构造方法不能被重写
- 返回值 和 形参 不能改变 方法名完全一致
- 重写的方法 可以用 @Override 注解显示;这个注解主要是进行校验(比人准确)
重写 和 重载的区别
区别点 | 重写(overrider) | 重载(overriding) |
参数列表 | 一致,不能修改 | 必须修改 |
返回类型 | 不能修改,除非构成父子关系 | 可以修改 |
访问限定符 | 不能修改,子类要大于等于父类 | 可以修改 |
方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现
4、向上转型 和 向下转型
静态和动态
静态绑定:也称前期绑定,在编译时根据参数的类型个数 进行判定哪个方法 — 重载
动态绑定: 也称后期绑定,在编译时不能确定方法的行为,要 在程序运行时,才能具体到 调用哪个方法
- 向上转型
- 重写
- 通过父类引用 调用这个父类和子类重写的方法
1、向上转型
向上转型:实际上是 new 一个 子类对象,将其当父类对象使用
格式:
父类类型 对象名 = new 子类类型();
父类类型的对象只能 调用父类 与 子类 共同带有的类型、方法
使用场景
- 直接赋值
- 方法传参: 父类类型作为参数,接受任意子类的对象
- 方法返回:返回类型 为 父类类型,返回值为子类对象
向上转型的优点: 让代码实现更加灵活
向上转型的缺点:不能调用子类特有的方法
2、向下转型
向上转型 就不能调用子类特有的方法,就需要将父类向下转型为 子类对象
向下转型是不安全的,所以 就要判定 父类是否引用的是该子类 —— instanceof
3、instanceof 关键字
instanceof 关键字:判断该对象是否被父类引用,是就返回 true
4、代码
package extern;
//形状
class Shape{
public void draw(){
System.out.println("画图形");
}
}
//菱形
class Rect extends Shape{
@Override
public void draw() {
System.out.println("◇");
}
}
//圆
class Cycle extends Shape{
@Override
public void draw() {
System.out.println("●");
}
}
//花
class Flower extends Shape{
@Override
public void draw() {
System.out.println("❀");
}
}
1. 没有向上转型 , 代码冗余
public class poly {
public static void main(String[] args) {
Rect rect = new Rect();
Cycle cycle = new Cycle();
Flower flower = new Flower();
//存储到 String 数组
String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};;
for (String shape:shapes) {
if (shape.equals("cycle")){
cycle.draw();
}else if (shape.equals("rect")) {
rect.draw();
} else if (shape.equals("flower")) {
flower.draw();
}
}
}
}
2. 向上转型 存储到数组 多态
public static void main(String[] args) {
Rect rect = new Rect();
Cycle cycle = new Cycle();
Flower flower = new Flower();
//向上转型 存储到数组
Shape[] shapes = {cycle,rect,cycle,rect,flower};
for (Shape shape:shapes) {
shape.draw();
}
}