【Java】继承与多态

继承
  • Object
    Java中,Object类是所有类的父类。
    因此,所有类都继承了Object类的方法,如getClass()hashCode()toString()equals()
public class Animal {
    private String picture;
    public void roam(){
        System.out.println("Animal: roaming");
    }
}
public class Dog extends Animal {
    public void roam(){
        System.out.println("Dog: roaming");
    }
}
public class Hippo extends Animal {
    public void roam(){
        System.out.println("Hippo: roaming");
    }
}
public class Test {
    public static void main(String[] args){
        Dog d = new Dog();
        System.out.println("d.getClass(): " + d.getClass());
        System.out.println("d.hashCode(): " + d.hashCode());
        System.out.println("d.toString(): " + d.toString());
        System.out.println("");

        Hippo h = new Hippo();
        System.out.println("h.getClass(): " + h.getClass());
        System.out.println("h.hashCode(): " + h.hashCode());
        System.out.println("h.toString(): " + h.toString());
        System.out.println("");

        if(d.equals(h)){
            System.out.println("true");
        }else{
            System.out.println("false");
        }
    }
}

在这里插入图片描述

  • Java不允许多重继承
    子类只能继承一个父类,不能继承多个父类
  • 使用 super获取父类
    super.roam()
public class Animal {
    private String picture;

    public void roam(){
        System.out.println("Animal: roaming");
    }
}
public class Hippo extends Animal {
    public void roam(){
        super.roam();
        System.out.println("Hippo: roaming");
    }
}
public class Test {
    public static void main(String[] args){
        Hippo h = new Hippo();
        h.roam();
    }
}
  • 通过super()调用父类的构造函数
    父类的构造函数必须在子类的构造函数之前调用。
public class Animal {
    public Animal(){
        System.out.println("making an animal");
    }
}
public class Hippo extends Animal {
    public Hippo(){
        super();
        System.out.println("Step 2: making a hippo");
    }
}
public class Test {
    public static void main(String[] args){
        Hippo hippo = new Hippo();
    }
}

在这里插入图片描述

public class Animal {
    private String name;
    public Animal(String theName){
        name = theName;
    }
    public String getName(){
        return name;
    }
}
public class Hippo extends Animal {
    public Hippo(String name){
        super(name);
    }
}
public class Test {
    public static void main(String[] args){
        Hippo hippo = new Hippo("Jeff");
        System.out.println(hippo.getName());
    }
}

在这里插入图片描述

  • 通过this()在构造函数中调用同类的另一个构造函数
    this()只能在构造函数中使用,且必须放在第一行;
    this()super()不能同时使用。
public class Animal {
    private String name;
    public Animal(){
        this("Tom");
    }
    public Animal(String theName){
        name = theName;
    }
    public String getName(){
        return name;
    }
}
public class Hippo extends Animal {
    public Hippo(String name){
        super(name);
    }
}
public class Dog extends Animal {

}
public class Test {
    public static void main(String[] args){
        Hippo hippo = new Hippo("Jeff");
        System.out.println("hippo'name is "+hippo.getName());

        Dog dog = new Dog();
        System.out.println("dog's name is "+ dog.getName());
    }
}

在这里插入图片描述

  • 访问权限
    • public
    • protected
    • private
  • 如何让类不可被继承
    • 使用final修饰类
      比如,public final class Animal{}
      另外,final也可以用来修饰类的方法,从而防止方法被覆盖。
    • 将类的构造函数标记为private
      比如,private Animal(){}
  • 方法覆盖
    • 参数类型必须相同,返回值类型必须兼容
    • 不能降低访问权限
多态
public class Animal {
    private String picture;

    public void roam(){
        System.out.println("Animal: roaming");
    }
}
public class Dog extends Animal {
    public void roam(){
        System.out.println("Dog: roaming");
    }
}
public class Test {
    public static void main(String[] args){
        Dog d = new Dog();
        d.roam();

        Animal dog = new Dog();
        dog.roam();
    }
}

在这里插入图片描述

抽象类
public class Animal {
    private String picture;
    public void roam(){
        System.out.println("Animal: roaming");
    }
}
public class Dog extends Animal {
    public void roam(){
        System.out.println("Dog: roaming");
    }
}
public class Hippo extends Animal {
    public void roam(){
        super.roam();
        System.out.println("Hippo: roaming");
    }
}
public class Test {
    public static void main(String[] args){
        Dog dog = new Dog();
        dog.roam();

        Hippo hippo = new Hippo();
        hippo.roam();

        Animal animal = new Animal();
        animal.roam();
    }
}

创建出Dog对象、Hippo对象很合理,但Animal对象却有些出人意料,它应该长什么样?几条腿?
也就是说Animal类不应该被初始化。
Dog、类Hippo是具体类,可以被初始化为对象;
Animal,则是抽象类,不应该被初始化的类,用abstract修饰。

public abstract class Animal {
    private String picture;
    public void roam(){
        System.out.println("Animal: roaming");
    }
}
public class Test {
    public static void main(String[] args){
        Animal animal = new Animal();
    }
}

在这里插入图片描述

抽象方法
  • 抽象方法没有实体
  • 抽象方法必须在抽象类中声明
  • 继承了抽象类的子类必须实现抽象类中的抽象方法,即抽象方法必须被覆盖
  • 抽象类中既可以有抽象方法,也可以有非抽象方法
public abstract class Animal {
    private String picture;
    public abstract void eat();
    public void roam(){
        System.out.println("Animal: roaming");
    }
}
public class Dog extends Animal {
    public void roam(){
        System.out.println("Dog: roaming");
    }
}
public class Hippo extends Animal {
    public void roam(){
        System.out.println("Hippo: roaming");
    }
}
public class Test {
    public static void main(String[] args){
    }
}

在这里插入图片描述

public abstract class Animal {
    private String picture;
    public abstract void eat();
    public void roam(){
        System.out.println("Animal: roaming");
    }
}
public class Dog extends Animal {
    public void eat(){
        System.out.println("Dog eat bone");
    }
    public void roam(){
        System.out.println("Dog: roaming");
    }
}
public class Hippo extends Animal {
    public void eat(){

    }
    public void roam(){
        System.out.println("Hippo: roaming");
    }
}
public class List {
    private Animal[] list = new Animal[5];
    private int nextIndex = 0;
    public void add(Animal a){
        if(nextIndex < list.length){
            list[nextIndex] = a;
            System.out.println("Add animal at " + nextIndex);
            nextIndex++;
        }
    }
}
public class Test {
    public static void main(String[] args){
        List list = new List();
        Dog d = new Dog();
        list.add(d);
        Hippo h = new Hippo();
        list.add(h);
    }
}

在这里插入图片描述

接口
  • 所有方法都是抽象的
    抽象类既可以有抽象方法,也可以有非抽象方法。
    接口,可以理解成100%的抽象类,即所有的方法都是抽象的。
  • 定义接口
    定义接口用interface
  • 实现接口
    实现接口用implements
public class Animal {
    private String picture;
    public void eat(){
        System.out.println("Animal:eat something");
    }
}
public class Canine extends Animal{
    public void roam(){
        System.out.println("Canine:roam");
    }
}
public interface Pet {
    void play();
    void beFriendly();
}
public class Dog extends Canine implements Pet {
    public void eat(){
        System.out.println("Dog: eat bone");
    }
    public void play(){
        System.out.println("Dog: play");
    }
    public void beFriendly(){
        System.out.println("Dog: be friendly");
    }
}
public class Test {
    public static void main(String[] args){
        Dog dog = new Dog();
        dog.eat();
        dog.roam();
        dog.play();
        dog.beFriendly();
    }
}

在这里插入图片描述
在这里插入图片描述
接口里声明的方法默认是publicabstract,所以上面就省写了,当然也可以像下面这样都写上,

public interface Pet{
    public abstract void play();
    public abstract void beFriendly();
}

在这里插入图片描述

静态方法
  • 静态方法用static标记
  • 静态方法通过类名来调用
    静态变量是通过类名来调用的,而不是通过实例来调用的,静态方法不依赖于实例变量。也正因为此,静态方法中不能调用非静态变量,或者说,静态方法中不能使用实例变量。如果在静态方法中使用实例变量,编译器会因为不知道到底使用哪个实例的变量而报错。
    在这里插入图片描述
    同样,静态方法中不能调用非静态方法,因为非静态方法依赖于实例变量。
    在这里插入图片描述
静态变量

静态变量由所有实例共享。
静态变量通过类名来访问。

public class Player {
    private String name;
    public static int playerCount = 0;
    public Player(String theName){
        name = theName;
        playerCount++;
    }
}
public class Test {
    public static void main(String[] args){
        System.out.println(Player.playerCount);

        Player one = new Player("Tom");
        System.out.println(Player.playerCount);

        Player two = new Player("John");
        System.out.println(Player.playerCount);
    }
}

在这里插入图片描述

final

final标识的变量,不能被修改;
final标识的方法,不能被覆盖;
final标识的构造函数,该构造函数所在类不能被继承,也不能创建该类的实例。

static final变量

static修饰的final变量是常数。
在这里插入图片描述

static final变量的初始化

static final变量有以下两种初始化方式。

  • 第一种:声明时赋值
public class Test {
    public final static double PI = 3.141592;
}
  • 第二种:在静态初始化程序中赋值
    静态初始化程序在加载类时执行,且在该类的其他所有代码之前执行。
public class Test {
    public static final double PI;
    static {
        PI = 3.141592;
    }
}
方法重载

函数名相同,参数不同。参数个数不同或参数类型不同。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值