继承和多态
继承
继承的概念
继承的基本语法
class 子类 extends 父类{ }
注意:
- 使用 extends 指定父类.
- Java 中一个子类只能继承一个父类 (而C++/Python等语言支持多继承).
- 子类会继承父类的所有 public 的字段和方法.
- 对于父类的 private 的字段和方法, 子类中是无法访问的.
- 子类的实例中, 也包含着父类的实例. 可以使用 super 关键字得到父类实例的引用
继承的好处
当我不使用继承时,代码如下:
class Animal {
public String name; public Animal(String name) {
this.name = name; } public void eat(String food) {
System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } } // Cat.java class Cat {
public String name; public Cat(String name) {
this.name = name; } public void eat(String food) {
System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } } // Bird.java class Bird {
public String name; public Bird(String name) {
this.name = name; } public void eat(String food) {
System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } public void fly() {
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿"); } }
class Animal {
public String name; public Animal(String name) {
this.name = name; } public void eat(String food) {
System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } } // Cat.java class Cat extends Animal{
public Cat(String name) {
// 使用 super 调用父类的构造方法. super(name); } } // Bird.java class Bird extends Animal{
public Bird(String name) {
super(name); } public void fly() {
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿"); } }
多态
什么是多态
多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作。
向上转型
Bird bird = new Bird("圆圆"); Animal bird2 = bird; // 或者写成下面的方式 Animal bird2 = new Bird("圆圆");
此时 bird2 是一个父类 (Animal) 的引用, 指向一个子类 (Bird) 的实例. 这种写法称为 向上转型.
动态绑定
当子类和父类中出现同名方法的时候, 再去调用会对前面的代码稍加修改,如以下代码:
class Animal {
public String name; public Animal(String name) {
this.name = name; } public void eat(String food) {
System.out.println("我是一只小动物"); System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } } // Cat.java class Cat extends Animal{
public Cat(String name) {
super(name); } @Override public void eat(String food) {
System.out.println("我是一只小猫"); System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } } // Bird.java class Bird extends Animal{
public Bird(String name) {
super(name); } @Override public void eat(String food) {
System.out.println("我是一只小鸟"); System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } public void fly() {
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿"); } } public class Main{
public static void main(String[] args){
Animal animal1 = new Animal("圆圆"); animal1.eat("谷子"); System.out.println("===================="); Animal animal2 = new Bird("扁扁"); animal2.eat("谷子"); } }

我们发现:
animal1 和 animal2 虽然都是 Animal 类型的引用, 但是 animal1 指向 Animal 类型的实例, animal2 指向Bird 类型的实例.
针对 animal1 和 animal2 分别调用 eat 方法, 发现 animal1.eat() 实际调用了父类的方法, 而animal2.eat() 实际调用了子类的方法.
因此, 在 Java 中, 调用某个类的方法, 究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为动态绑定
向下转型
向上转型是子类对象转成父类对象, 向下转型就是父类对象转成子类对象. 相比于向上转型来说, 向下转型没那么常见,但是也有一定的用途.
class Animal {
public String name; public Animal(String name) {
this.name = name; } public void eat(String food) {
System.out.println("我是一只小动物"); System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } } // Cat.java class Cat extends Animal{
public Cat(String name) {
super(name); } @Override public void eat(String food) {
System.out.println("我是一只小猫"); System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } } // Bird.java class Bird extends Animal{
public Bird(String name) {
super(name); } @Override public void eat(String food) {
System.out.println("我是一只小鸟"); System.out.println(this.name+"正在干饭,并表示"+food+"很不错"); } public void fly() {
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿"); } } public class Main {
public static void main(String[] args) {
Animal animal2 = new Bird("扁扁"); animal2.fly(); } }

注意:
编译过程中, animal 的类型是 Animal, 此时编译器只知道这个类中有一个 eat 方法, 没有 fly 方法.
虽然 animal 实际引用的是一个 Bird 对象, 但是编译器是以 animal 的类型来查看有哪些方法的。如果需要引用fly方法则需要对它进行向下转型
操作如下
Bird bird = (Bird)animal2; bird.fly();

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232315.html原文链接:https://javaforall.net
