Java基础之多态、抽象类

146 阅读4分钟

「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战

1 多态

1.1 多态概述

  • 同一个对象,不同时刻表现出来的不同形态
  • 多态的分类:具体类多态、抽象类多态、接口多态
  • 多态的前提和体现
    • 1,有继承/实现关系
    • 2,有方法重写
    • 3,有父类引用指向子类对象
  • 父类
package ceshi;

public class Animal {
    public void eat(){
        System.out.println("吃东西");
    }
}
  • 子类
package ceshi;

public class Cat extends Animal{ //1,有继承/实现关系
    //2,有方法重写
    @Override
    public void eat() { //重写快捷方法直接写eat按回车自动生成
        System.out.println("猫吃东西");
    }
}
  • 测试类
package ceshi;

public class Demo {
    public static void main(String[] args) {
        //3、有父类引用指向子类对象
        Animal a = new Cat();
    }
}

1.2 多态中成员访问特点

  • 成员变量:编译看左边,运行看左边
  • 成员方法:编译看左边,运行看右边
  • 为什么成员方法和成员变量的访问不一样呢? 因为成员方法有重写而成员变量没有重写(还是父类的)
  • 父类
package ceshi;

public class Animal {

    public int age = 20;
    public void eat(){
        System.out.println("动物吃东西");
    }
}
  • 子类
package ceshi;

public class Cat extends Animal{ //1,有继承/实现关系
    //2,有方法重写
    public int age = 40;
    public int weight = 10;
    @Override
    public void eat() { //3,重写快捷方法直接写eat按回车自动生成
        System.out.println("猫吃东西");
    }

    public void playGame(){
        System.out.println("猫玩捉迷藏");
    }
}
  • 测试:
package ceshi;

public class Demo {
    public static void main(String[] args) {
        //有父类引用指向子类对象
        Animal a = new Cat();

        a.eat(); //猫吃东西
        //对于方法的调用: 编译(写代码)看左边Animal,运行看右边 Cat
        //看左边指的是看等号的左边,等号左边是Animal,会找Animal里面的eat方法,有方法才不报错
        //运行的时候看等号的右边,等号右边是Cat,执行Cat里面的eat方法
//        a.playGame; 报错,父类有没这个方法

        System.out.println(a.age); //20;对于变量的调用: 编译看左边,运行看左边
//        System.out.println(a.weight); 报错
    }
}

1.3 多态的好处和弊端

  • 好处:提高程序的扩展性
  • 具体体现:定义方法时,使用父类作为参数,将来在使用的时候,使用具体的子类参与操作
  • 弊端:不能使用子类的特有功能

1.3 多态中的转型

  • 向上转型:从子到父,父类引用指向子类对象

  • 向下转型:从父到子,父类引用转为子类对象

  • 转型的好处:可以使用子类的特有功能

  • 测试:

package ceshi;

public class Demo {
    public static void main(String[] args) {
        //多态
        Animal a = new Cat(); //向上转型
        a.eat();
//        a.playGame(); 报错,因为编译看左边Animal中没有这个方法

        //向下转型
        Cat c = (Cat)a;
        c.eat(); //猫吃东西
        c.playGame(); //猫玩捉迷藏

    }
}

2 抽象类

2.1 抽象类概述

  • 在Java中,一个 没有方法体 的方法应该定义为 抽象方法 ,如果类中有 抽象方法 ,该类必须定义为 抽象类

  • 所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。 注意:

  • 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

  • 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

  • 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。

  • 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。

  • 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

  • 关键字:abstract

2.2 抽象类的特点

  • 1,抽象类和抽象方法必须使用 abstract ([æbˈstrækt])关键字修饰
public abstract class 类名(){
	public abstract void 方法名();
}
  • 2,抽象类中不一定有抽象方法,有抽象方法的类一定是 抽象类
  • 3,抽象类不能实例化,但是可以参照多态的方式,通过子类对象实例化,这叫 抽象类多态
  • 4,抽象类的子类要么重写所有抽象方法,要么它本身就是一个抽象类

2.3 抽象类成员特点

  • 成员变量:可以是变量,可以是常量
  • 构造方法:有构造方法但是本身不能实例化,用于子类访问父类数据初始化(多态的方式实例化)
  • 成员方法: 1,可以是抽象方法,限定子类必须重写 2,还可以上非抽象方法,提高代码的复用性