Java查漏补缺系列——abstract class和interface区别

abstract class

声明方法的存在而不去实现它的类被叫做抽象类,使用abstract 声明类,它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。
不能创建抽象类的实例(不能使用new创建对象)。然而抽象类可以定义变量,引用具体子类的实例(对象)。
不能有抽象构造函数或抽象静态方法。
抽象类只能被继承,在具体子类中必须实现全部抽象方法。

案例:

package day03;
public class abstracClassDemo {
    public static void main(String[] args){
        //Shape s = new Shape();//抽象类不能直接实例化(不能使用new创建对象)
        Shape s = new Circle(3,4,5);
        s.down();
        System.out.println(s.contains(3, 4));
    }
}
abstract class Shape{//抽象的图形,使用abstract 声明类
    int x;
    int y;
    public abstract boolean contains(int x,int y);//抽象类可以保护抽象方法,使用abstract声明的方法,抽象方法不能有方法体
    public void down(){//可以包含非抽象类方法
        y++;
    }
}

abstract class square{
    public square(){//抽象类中可以有构造函数
    }
    public abstract boolean around();
}

//实现抽象类用extends,抽象类只能被继承,在具体子类中必须实现全部抽象方法
class Circle extends Shape /*extends square*/{//一个类只能继承一个抽象类。 
    int r;
    public Circle(int x,int y,int r){
        this.x = x;
        this.y = y;
        this.r = r;
    }
    public boolean contains(int x, int y) {
        int a = this.x - x;
        int b = this.y - y;
        return Math.sqrt(a*a+b*b)<=r;
    }
}

interface

接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。

案例一:

package day03;

public class interfaceDemo01 {
    public static void main(String[] args){
        Runner tt=new TT();//接口的引用指向实现的对象
        System.out.println(tt.i);
        System.out.println(Runner.i);
        tt.start();
        Eater ee=new TT();
        System.out.println(ee.j);
        System.out.println(Eater.j);
        ee.start();
        Drinker dd=new TT();
        dd.getWater();
        dd.drinkWater();
    }
}

//定义接口
interface Runner{
    //int i;//必须初始化
    int i=3;
    //i = i+1;//接口中定义的变量只能是public static final类型,并且默认即为public static final类型,不可以再改变。
    public void start();
    void run();
    void stop();

    /*接口中不能含有非抽象类
    public void down(){//可以包含非抽象类方法
        y++;
    }
    */

    /*接口中不能有构造函数
    public Runner(){

    }
    */

}
//接口间可以继承
interface Eater extends Runner{
    public static int j=4;
    //private int i= 1;//接口中不能含有私有变量
    void openMouth();
    void upAndDown();
    void goIn();
}

interface Drinker{
    void getWater();
    void drinkWater();
}

//引用接口用implements
class TT implements Eater,Drinker{//一个类可以实现多个接口
    public void start(){
        System.out.println("---------start()-------");
    }
    public void run(){
        System.out.println("---------run()-------");
    }
    public void stop(){
        System.out.println("---------stop()-------");
    }
    public void openMouth(){
        System.out.println("---------openMouth()-------");
    }
    public void upAndDown(){
        System.out.println("---------upAndDown()-------");
    }
    public void goIn(){
        System.out.println("---------goIn()-------");
    }

    public void getWater() {
        System.out.println("---------getWater()-------");
    }
    public void drinkWater() {
        System.out.println("---------drinkWater()-------");
    }
}

案例二:

package day03;

public class interfaceDemo02 {
    public static void main(String[] args){
        CareAnimalable c = new Worker();
        //Worker w = (Worker)c;
        interfaceDemo02 t = new interfaceDemo02();
        t.t(c); //多态
        c = new Farmer();
        t.t(c); 
    }
    public void t(CareAnimalable c){//尽量定义为接口或父类的引用
        c.feed();
        c.play();
    }
}

//定义一个接口
interface CareAnimalable{
    public void feed();
    public void play();
}

class Worker implements CareAnimalable{
    public void feed(){
        System.out.println("-----feed()----");

    }
    public void play(){
        System.out.println("-----play()----");

    }
}

class Farmer implements CareAnimalable{
    public void feed(){
        System.out.println("-----Farmer feed()----");

    }
    public void play(){
        System.out.println("-----Farmer play()----");

    }
}

区别

下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。

2.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

3.抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

4.抽象类中可以包含静态方法,接口中不能包含静态方法

5.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。

6.一个类可以实现多个接口,但只能继承一个抽象类。

7.尽管interface实现类及abstrct class的子类都必须要实现相应的抽象方法,但实现的形式不同。interface中的每一个方法都是抽象方法,都只是声明的 (declaration, 没有方法体),实现类必须要实现。而abstract class的子类可以有选择地实现。
这个选择有两点含义:
一,是abastract class中并非所有的方法都是抽象的,只有那些冠有abstract的方法才是抽象的,子类必须实现。那些没有abstract的方法,在Abstrct class中必须定义方法体。
二,是abstract class的子类在继承它时,对非抽象方法既可以直接继承,也可以覆盖;而对抽象方法,可以选择实现,也可以通过再次声明其方法为抽象的方式,无需实现,留给其子类来实现,但此类必须也声明为抽象类。既是抽象类,当然也不能实例化。

8.abstract class是interface与Class的中介。
interface是完全抽象的,只能声明方法,而且只能声明pulic的方法,不能声明private及protected的方法,不能定义方法体,也 不能声明实例变量。然而,interface却可以声明常量变量,并且在JDK中不难找出这种例子。但将常量变量放在interface中违背了其作为接 口的作用而存在的宗旨,也混淆了interface与类的不同价值。如果的确需要,可以将其放在相应的abstract class或Class中。
abstract class在interface及Class中起到了承上启下的作用。一方面,abstract class是抽象的,可以声明抽象方法,以规范子类必须实现的功能;另一方面,它又可以定义缺省的方法体,供子类直接使用或覆盖。另外,它还可以定义自己 的实例变量,以供子类通过继承来使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值