目录
一、多态
1、向上转型
1.1 定义
1.2 向上转型举例
1.3 代码实例
2、方法重写
2.1 满足规则
2.2 注意事项
3、动态绑定
4、向上转型发生的时机
4.1 直接赋值
4.2 返回值
4.3 传参
5、super关键字
5.1 含义及用法
5.2 super关键字与this关键字区别
6、多态的好处
二、抽象类
1、语法规则
2、注意事项
3、抽象类作用
三、接口
1、语法规则
2、实现多个接口
3、接口间的继承
4、接口和抽象类对比
一个父类的引用指向一个子类的实例,通过父类引用调用父类和子类同名覆盖方法。此时,如果父类引用指向的子类对象不一样,调用这个重写的方法,表现得行为也不一样。
例一: Dog dog = new Dog("旺旺",14);
Animal animal = dog;
例二: Animal animal = new Dog("旺旺",14);
向上转型之后,只能通过父类的引用访问父类自己特有的属性和方法,不能访问子类特有的方法和属性
// 先创建父类Animal 和子类Dog class Animal{ public String name; public int age; public Animal(String name, int age) { this.name = name; this.age = age; } public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } } class Dog extends Animal{ public Dog(String name, int age) { super(name, age); } } // 向上转型并输出结果 public class test { public static void main(String[] args) { Dog dog = new Dog("旺旺",14); Animal animal = dog; System.out.println(animal.toString()); } } 运行结果: Dog{name='旺旺', age=14}
动态绑定又称运行时绑定,是多态的基础
通过父类引用调用父类和子类的同名覆盖方法,此时会发生动态绑定。绑定子类的同名函数
class Animal{ public String name; public int age; public Animal(String name, int age) { this.name = name; this.age = age; } public void eat(){ System.out.println("吃东西!"); } } class Dog extends Animal{ public Dog(String name, int age) { super(name, age); } @Override //子类重写eat函数 public void eat() { System.out.println("dog在吃!"); } } public class test { public static void main(String[] args) { Animal animal = new Dog("旺旺",14); //向上转型 animal.eat(); // 通过父类引用调用父类和子类同名覆盖方法 } }
运行结果:
dog在吃!
Animal animal = new Dog("旺旺",14);
class Animal { //定义父类 public String name; public int age; public Animal(String name, int age) { //构造方法 this.name = name; this.age = age; } public void eat(){ System.out.println("吃东西!"); //普通方法 } } class Dog extends Animal { //定义子类 public Dog(String name, int age) { super(name, age); } @Override //重写eat方法 public void eat() { System.out.println("dog在吃!"); } } public class test1 { public static Animal func(){ //定义返回值为Dog 类型的方法 Dog dog =new Dog("旺旺",14); return dog; } public static void main(String[] args) { Animal animal = func(); animal.eat(); } }
运行结果:
dog在吃!
class Animal { public String name; public int age; public Animal(String name, int age) { this.name = name; this.age = age; } public void eat(){ System.out.println("吃东西!"); } } class Dog extends Animal { public Dog(String name, int age) { super(name, age); } @Override 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 class test1 { public static void func(Animal animal){ animal.eat(); } public static void main(String[] args) { Dog dog = new Dog("旺旺",14); //new哪个就调用哪个子类的eat函数 func(dog); Cat cat = new Cat("喵喵",3); func(cat); } }
运行结果:
旺旺在吃!
喵喵在吃!
(1)含义: super 表示获取到父类实例的引用
(2)用法
public Bird(String name) { super(name); }
public class Bird extends Animal { public Bird(String name) { super(name); } @Override public void eat(String food) { // 修改代码 , 让子调用父类的接口 . super.eat(food); } }
区别 | this | super | |
1 | 概念 | 访问本类中的属性和方法 | 由子类访问父类的属性和方法 |
2 | 查找范围 | 先查找本类,本类没有则调用父类 | 直接调用父类 |
3 | 特殊 | 表示当前对象 | 无 |
抽象方法:该方法没有具体的实现,使用abstract修饰
抽象类:包含抽象方法的类称为抽象类
abstract class 类名 { abstract public void 方法名(); }
(1)抽象类不能直接实例化(即不能new对象)
(2)抽象方法不能是 private 和 final 修饰的
(3)抽象类中可以包含其他的非抽象方法, 也可以包含字段. 这个非抽象方法和普通方法的规则都是一样的, 可以被重写, 也可以被子类直接调用
(4)如果一个普通类继承了抽象类,则普通类需要重写抽象类中的抽象方法
(5)一个抽象类A继承了另一个抽象类B,抽象类A中可以不重写抽象类B中的抽象方法。但是一旦抽象类A被继承后,继承的子类需要重写抽象类A和抽象类B中的所有抽象方法。
抽象类存在的最大意义就是为了被继承
interface 接口名 { //定义接口 方法 属性 } class 类名 implements 接口名{ //实现接口 }
定义一组接口, 分别表示 "会飞的", "会跑的", "会游泳的",再定义青蛙类,因为青蛙, 既能跑, 又能游,因此青蛙类需实现两个接口。
interface IFlying { void fly(); } interface IRunning { void run(); } interface ISwimming { void swim(); } class Frog extends Animal implements IRunning, ISwimming { public Frog(String name) { super(name); } @Override public void run() { System.out.println(this.name + "正在往前跳"); } @Override public void swim() { System.out.println(this.name + "正在蹬腿游泳"); } }
IDEA 中使用 ctrl + i 快速实现接口
接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字
区别 | 抽象类 | 接口 | |
1 | 结构组成 | 普通类+抽象方法 | 抽象方法+全局常量 |
2 | 权限 | 各种权限 | public |
3 | 子类使用 | extends关键字 | implements关键字 |
4 | 关系 | 一个抽象类可以实现若干接口 | 接口不能继承抽象类,但是接口可以使用关键字extends关键字实现多个父接口 |
5 | 子类限制 | 一个子类只能继承一个抽象类 | 一个子类可以实现多个接口 |