抽象类和接口的区别

一.抽象类

  
  
观察代码:

class Shape{
    public void draw(){
        //啥都不干
    }
}

class Cycle extends Shape{
    @Override
    public void draw() {
        System.out.println("⚪");
    }
}

class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("♦");
    }
}

public class Test {
    public static void main(String[] args) {
        Shape shape1=new Cycle();
        Shape shape2=new Rect();
        shape1.draw();
        shape2.draw();
    }
}

//打印结果
⚪
♦

  上述代码中,父类Shape中的draw方法并没有什么实际的工作,主要绘制图形都是由子类的draw方法来完成的。像这样的没有实际工作的方法,就可以将它设计为一个抽象方法。

abstract class Shape{
    abstract public void draw();
}

  1.在draw方法前加上abstract关键字,表示这是一个抽象方法,抽象方法没有方法体,不能执行具体的代码。
  2.对于包含抽象方法的类,系统将强制要求该类被声明为抽象类


注意事项:
 1.抽象类不可以被实例化
 2.抽象方法不能是private的
 3.抽象类中可以包含其他的非抽象方法,也可以包含字段,这个非抽象方法和普通方法的规则是一样的,可以被重写也可以被子类直接调用


抽象类的特点:
 ①包含抽象方法的类叫抽象类(抽象类中不一定含有抽象方法)
 ②抽象类不能被实例化,要想使用,只能创建该类的子类,然后让子类重写抽象类中的抽象方法
 ③抽象类中可以有抽象方法,也可以有普通方法或成员变量
 ④只要继承抽象类,子类就一定要重写抽象类里的抽象方法
 ⑤抽象类A如果继承了抽象类B,类A可以选择重写或者不重写抽象类B中的方法



二.接口

  

  接口,比抽象类更加抽象,抽象类中可以包含非抽象方法,而接口中都是抽象方法,字段只能是静态常量。

观察代码:

interface Ishape{          //定义接口
    void draw();
}

class Cycle implements Ishape{     //实现接口
    @Override
    public void draw(){
        System.out.println("⚪");
    }
}

public class Test{
    public static void main(String[] args) {
        Ishape shape=new Cycle();
        shape.draw();
    }
}

//打印结果


 1.使用interface定义一个接口
 2.接口中的方法一定是抽象方法,因此可以省略abstract
 3.接口中的方法一定是public,因此可以省略public
 4.Cycle使用implements实现接口
 5.在调用时可以创建一个接口的引用,对应到一个子类的实例
 6.接口不能被单独实例化
 7.接口可以同时实现多个
 8.只要普通类实现这个接口,那么接口中的方法都必须重写
 9.接口和接口之间是继承关系,接口可以多继承(接口间的继承相当于把多个接口合并在一起)
在这里插入图片描述

实现多个接口


  在Java中只支持单继承,但是可以实现多个接口,也能达到多继承类似的效果

代码举例:

class Animal{
    protected  String name;

    public Animal(String name){
        this.name=name;
    }
}

//定义三个接口
interface  Iflying{
    void fly();
}

interface  Irunning{
    void run();
}

interface  Iswimming{
    void swim();
}

//Cat类继承Animal类并且实现Irunning接口
class Cat extends Animal implements Irunning{
    public Cat(String name){
        super(name);
    }

    @Override
    public void run() {
        System.out.println(this.name+"running");
    }
}

//Fish类继承Animal类并且实现Iswimming接口
class Fish extends Animal implements Iswimming{
    public Fish(String name){
        super(name);
    }

    @Override
    public void swim() {
        System.out.println(this.name+"swimming");
    }
}

//Duck类继承Animal类并且实现Irunning,Iflying,Iswimming三个接口
class Duck extends Animal implements Irunning,Iflying,Iswimming{
    public Duck(String name){
        super(name);
    }

    @Override
    public void swim() {
        System.out.println(this.name+"swimming");
    }
    @Override
    public void run() {
        System.out.println(this.name+"running");
    }
    @Override
    public void fly() {
        System.out.println(this.name+"flying");
    }
}


public class Test{

   //实现一个方法叫散步
    public static void walk(Irunning running){
        System.out.println("散步");
        running.run();
    }
    
    public static void main(String[] args) {
        Cat cat=new Cat("小猫");
        walk(cat);
       Duck duck=new Duck("可达鸭");
        walk(duck);
    }
}

//打印结果
散步
小猫running
散步
可达鸭running

  在上述代码walk方法内部,并不需要关心到底是哪种动物,只要参数是会跑的就行

  注意: 一个类要先继承另一个类然后再实现接口,接口可以实现多个,接口名之间用逗号隔开即可。

  

小结:

  
两者核心区别:
  抽象类中可以有普通方法和普通字段,这样的普通方法和字段可以被子类直接调用,而在接口中不能包含普通方法,子类必须重写所有的抽象方法

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值