Java 抽象类和接口

 

抽象类

•概念

  我们都知道在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的;

  但是并不是所有的类都是来描述对象的。

  如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类。

  比如  new Animal() ,我们都知道这个是产生一个动物 Animal 对象;

  但是这个Animal具体长成什么样子我们并不知道,它没有一个具体动物的概念,所以他就是一个抽象类;

  需要一个具体的动物,如狗、猫来对它进行特定的描述,我们才知道它长成啥样。

 

  抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

  由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。

  也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

  在 Java 中,抽象类表示的是一种继承关系,一个类只能继承一个抽象类。

•抽象方法

  如果你想设计这样一个类:

    该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

  Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

  抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

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

  通过 abstract 定义了一个抽象类 Animal;

  并定义了一个抽象方法 cry(),通过代码可以看到只有方法体的声明,而没有具体实现。

特点

  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

•如何定义?

  在Java语言中使用 abstract class 来定义抽象类。

  定义 Animal 为抽象类;

Animal.java

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

  定义 Dog,Cat 类继承 Animal类 并实现其抽象方法;

Text.java

public class Test {

    public static void main(String[] args) {
        
        Animal d = new Dog();
        Animal c = new Cat();
        
        d.cry();
        c.cry();
    }
}
class Dog extends Animal{

    @Override
    public void cry() {
        // TODO Auto-generated method stub
        System.out.println("汪汪汪");
    }
}
class Cat extends Animal{

    @Override
    public void cry() {
        // TODO Auto-generated method stub
        System.out.println("喵喵喵");
    }
}

  猫、狗都是动物类的子类,由于cry()为抽象方法,所以Cat、Dog必须要实现cry()方法。

运行结果

  

•使用要点

  • 抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。
  • 抽象方法必须由子类来进行重写。
  • 只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。
  • 抽象类中可以包含具体的方法,当然也可以不包含抽象方法。
  • 子类中的抽象方法不能与父类的抽象方法同名。
  • abstract 不能与 final 并列修饰同一个类。
  • abstract 不能与 private、static、final 或 native 并列修饰同一个方法。

 


接口

•概念

  接口(英文:Interface),在 Java 编程语言中是一个抽象类型,是抽象方法的集合,接口通常以 interface 来声明。

  一个类通过继承接口的方式,从而来继承接口的抽象方法。

  接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。

  类描述对象的属性和方法,接口只包含类要实现的方法。

  接口是用来建立类与类之间的协议,它所提供的只是一种形式,而没有具体的实现。

  同时实现该接口的实现类必须要实现该接口的所有方法,除非将该类定义成抽象类;

  通过使用 implements 关键字,他表示该类在遵循某个或某组特定的接口;

  同时也表示着 "interface" 只是它的外貌,但是现在需要声明它是如何工作的。

  接口是抽象类的延伸,Java 为了保证数据安全是不能多重继承的,也就是说继承只能存在一个父类;

  但是接口不同,一个类可以同时实现多个接口,不管这些接口之间有没有关系;

  所以接口弥补了抽象类不能多重继承的缺陷,但是推荐继承和接口共同使用;

  因为这样既可以保证数据安全性又可以实现多重继承。

•接口的声明格式

[访问修饰符]  interface 接口名 extends 父接口1,父接口2…{
  常量定义;  
  方法定义;
}

•接口的特点

  • 接口中每一个方法是隐式抽象的
    • 接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)
  • 接口中可以含有变量
    • 但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)
  • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
  • extends : 接口可以多继承。

•抽象类和接口的区别

  • 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
  • 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

•接口的声明

Animal.java

interface Animal {
    /*public static final*/ int num = 100;//写与不写都是 public static final 类型
    /*public abstract*/ void cry();//写与不写都是 public abstract 修饰的
}

Test.java

public class Test {

    public static void main(String[] args) {
        
        //接口不能创建实例,但是可用于声明引用变量类型
        Animal d = new Dog();
        Animal c = new Cat();
        
        d.cry();
        c.cry();
    }
}
//子类通过 implements 来实现接口中的规范
class Dog implements Animal{

    //一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的
    @Override
    public void cry() {
        // TODO Auto-generated method stub
        System.out.println("汪汪汪");
    }
}
class Cat implements Animal{

    //一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的
    @Override
    public void cry() {
        // TODO Auto-generated method stub
        System.out.println("喵喵喵");
    }
}

运行结果

  

 


声明

  参考资料:

posted @ 2021-02-03 21:59  MElephant  阅读(152)  评论(0编辑  收藏  举报