抽象方法和抽象类

  在我们学过了继承和多态后,我们看到如果子类重写了父类的方法,那么运行时就不会去管父类里的这个方法的内容了,那么我们是否可以用一种方法去省略父类中的内容而不报错呢?比如有一个的代码:

class Animal{
    public void eat(){
    System.out.println("动物吃东西");
    }
}


class Dog extends Animal{
    public void eat(){
    System.out.println("狗吃骨头");
    }
}


class Test{
    public static void main(String[] args){
    Animal animal=new Dog();
    animal.eat();
    }
}

这个代码运行过后的结果是 狗吃骨头 ,而不是 动物吃东西 ,因此我们可以猜测在运行时是从子类开始,再到父类终止。因此我们想:父类的方法是否可以省略?

我们再写一个代码:

class Animal{
    public void eat(){

    }
}


class Dog extends Animal{
    public void eat(){
    System.out.println("狗吃骨头");
    }
}


class Test{
    public static void main(String[] args){
    Animal animal=new Dog();
    animal.eat();
    }
}

再看这个代码,结果还是狗吃骨头,而且父类里的方法似乎已经省略到了最简,如果再省略掉大括号的话,那么编译时就会报错。看起来好像已经是最简化了,但实际上还有一种方法可以使其省略大括号,这个方法就叫做抽象方法,抽象方法要用 abstract 修饰。如下:

public abstract class Animal{
    public abstract void eat();
}


class Dog extends Animal{
    public void eat(){
    System.out.println("狗吃骨头");
    }
}


class Test{
    public static void main(String[] args){
    Animal animal=new Dog();
    animal.eat();
    }
}

但我们明明只改变抽象方法,为什么类也要改成抽象的呢?因为当你定义了一个抽象方法后,如果这个类不是抽象类,编译时就会报错。因此我们要知道,有抽象方法的类一定要是抽象类。那么我们就有疑问了,抽象类是否一定要有抽象方法呢?其实不然,抽象类里还可以有其他方法,如:

abstract class Animal{
    static void feed();
    default void drink();
}

这些方法不是抽象方法,但依旧可以在抽象类中存在,而且系统不会报错。所以我们又知道了:抽象类中的方法并不一定要有抽象方法。我们再来继续看一个代码:

public abstract class Animal{
    public abstract void eat();
    public abstract void walk();
}


class Dog extends Animal{
    public void eat(){
    System.out.println("狗吃骨头");
    }
}


class Test{
    public static void main(String[] args){
    Animal animal=new Dog();
    animal.eat();
    }
}

这个代码看起来好像没什么问题,但当你编译时它还是会报错。原因就是对于抽象类中的方法,子类必须要全部重写抽象方法,如果没有写全,则会报错。但对于Dog类,我们其实还可以给它定义一个子类,那么Dog类就会变成一个抽象类,便可以不用重写Animal类的抽象方法,而是由这个子类重写抽象方法。

所以我们又知道了:若一个类继承自抽象类必须重写抽象方法,否则该类也是抽象类

我们可以看到抽象类的强制性,如果你没有在子类重写抽象方法,它就会直接报错,这也可以在我们写代码时很好地提醒我们。

对于抽象类,其中的public abstract 可以当作 interface(接口),接口的定义和类的定义类似,我们可以看看接口的形式:

interface A{
    void eat();
    void walk();
}

而接口的一些性质实际上和抽象类也是类似的,接口中除了可以用抽象方法外,还可以用其他方法,如:static void feed(); 等等,但在这里我就不多讲了。

而接口有所不同的是,接口只有定义而没有实现,如果你想要实现里面的方法,那么必须要有子类来实现(implements)它。如:

interface A{
    void eat();
}


class Dog implements A{
    public void eat(){
    System.out.println("狗吃骨头");
    }
}


class Test{
    public static void main(String[] args){
    A a=new Dog();
    a.eat();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值