(三)、抽象类和接口的区别

一、抽象类(Abstract Class)

(一)概念

1.抽象类是关键字Abstract修饰的类,即为抽象类,但是没有方法体( 没有{ } ),只有声明方法,抽象方法强制子类覆盖。

2.抽象抽象即不能被实例化,不能创建对象(不能new, 但是可以super)。而不能被实例化就无用处,所以抽象类只能作为基类(父类),即被继承的类,即抽象类必须得有子类,自己的功能才能得以运行。

3.抽象类中可以包含抽象方法也可以不包含,但具有抽象方法的类一定是抽象类。

4.抽象类的方法只是定义了子类应该具备的行为,但是没有给出怎么去完成行为的功能代码,要交给子类去根据自身特殊情况去完成该父类申明的功能。

5.抽象类中可以有普通方法,可以声明成员变量。

(二)抽象类的使用原则

1.被继承性:抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;

2.抽象性:抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;

3.抽象类必须要有子类,使用extends继承;

4.子类(如果不是抽象类)则必须重写抽象类中的全部抽象方法;如果子类没有实现父类的抽象方法,则必须将子类也定义为abstract类。

5.抽象类中的普通方法可以有选择型的来决定是否需要重写。

//抽象类
abstract class A{
    //普通方法
    public void fun(){    
        System.out.println("存在方法体的方法");
    }
    //抽象方法,没有方法体,有abstract关键字作修饰
    public abstract void print();
}
//单继承特性
class B extends A{  //B类是抽象类的子类,是一个普通类
    @Override
    public void print(){    //强制要求重写
        System.out.println("Why is more important than what!");
    }
}
//主函数
public class test{
    public static void main(String[] args) {
        A a = new B();     //多态,向上转型
        a.print();
        a.fun(); //被子类所重写过的方法
    }
}

运行结果如下:

(三)为什么不能进行实例化?

当一个类实例化后,就意味着对象可以调用类中的属性或者方法,但在抽象类里存在抽象方法,而抽象方法没有方法体,没有方法体就无法进行调用,既然无法进行方法调用,又怎么去产生实例化对象呢。

(四)抽象类的使用限制

1.抽象类中有构造方法吗?

  由于抽象类里会存在一些属性,那么抽象类一定存在构造方法,其存在目的就是为了属性的初始化。并且子类对象实例化的时候,依然满足先执行父类构造,再执行子类构造的顺序。

abstract class A{//定义一个抽象类
    
    public A(){
        System.out.println("*****A类构造方法*****");
    }

    public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
    
}

//单继承
class B extends A{//B类是抽象类的子类,是一个普通类

    public B(){
        System.out.println("*****B类构造方法*****");
    }

    @Override
    public void print(){//强制要求覆写
        System.out.println("Hello World! ");
    }
}

public class TestDemo{
    public static void main(String[] args) {
        A a = new B(); //向上转型
    }
}   //最后依次输出A类和B类的构造方法

运行结果如下:

2.抽象类中可以用final声明吗?

  不能,因为抽象类必须有子类,而final声明的类不能有子类。

3.抽象类能否用static声明?

  外部抽象类不允许使用static声明,而内部的抽象类运行使用static声明。

  用static声明的内部抽象类相当于一个外部抽象类,继承的时候使用"外部类.内部类"的形式表示类名称

abstract class A{//定义一个抽象类
    
    static abstract class B{//static定义的内部类属于外部类
        public abstract void print();
    }
    
}

class C extends A.B{
    
    public void print(){
        System.out.println("**********");
    }
}
public class TestDemo {

    public static void main(String[] args) {
        A.B ab = new C();//向上转型
        ab.print();
    }

}

运行结果如下:

4.可以直接调用抽象类中用static声明的方法么?

  任何时候,如果要执行类中的static方法的时候,都可以在没有对象的情况下直接调用,对于抽象类也一样。 

 

abstract class A{    //定义一个抽象类

    public static void print(){
        System.out.println("Hello World !");
    }

}

public class TestDemo{
    public static void main(String[] args) {
        A.print();
    }
}

运行结果如下:

5.有时候由于抽象类中只需要一个特定的系统子类操作,所以可以忽略外部子类。

  这样的设计在系统类库中会比较常见,目的是对用户隐藏不需要知道的子类。

abstract class A{    //定义一个抽象类

    public abstract void print();

    private static class B extends A{    //内部抽象类子类

        public void print(){    //覆写抽象类的方法
            System.out.println("Hello World !");
        }
    }

    //这个方法不受实例化对象的控制
    public static A getInstance(){
        return new B();
    }
}

public class TestDemo{
    public static void main(String[] args) {
        //此时取得抽象类对象的时候完全不需要知道B类这个子类的存在
        A a = A.getInstance();
        a.print();
    }
}

运行结果如下:

(五)抽象类的应用——模板设计模式 

  所有的子类如果要想正常的完成操作,必须按照指定的方法进行覆写才可以,而这个时候抽象类所起的功能就是一个类定义模板的功能。

 

二、接口(Interface)

接口在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口定义了一种规范,规定一个类必须做什么,但是不管如何具体去做。

(一)接口与类相似点

  一个接口可以有多个方法;

  接口文件保存在 .java 结尾的文件中,文件名使用接口名。

  接口的字节码文件保存在 .class 结尾的文件中。

  接口相应的字节码文件必须在与包名称相匹配的目录结构中。

(二)接口与类的区别

  接口不能实例化对象;

  接口没有构造方法;

  接口中的所有方法必须是抽象方法;

  接口不能包含成员变量,除了static和final变量;

  接口不是被类继承了,而是要被类实现;

  接口支持多继承;

  接口只能继承接口,不能继承类;

  接口里的方法默认修饰符是public abstract;

  接口里的字段全是全局变量,默认修饰符是public static final。

(三)接口特性

  接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。

  接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。

  接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

(四)接口的继承

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

Java中类不允许多继承但接口可以。

// 文件名: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}
 
// 文件名: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}
 
// 文件名: Hockey.java
public interface Hockey extends Sports
{
   public void homeGoalScored();
   public void visitingGoalScored();
   public void endOfPeriod(int period);
   public void overtimePeriod(int ot);
}

(五)接口的实现

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。

类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

/* 文件名 : Animal.java */
interface Animal {
   public void eat();
   public void travel();
}

/* 文件名 : test.java */
public class MammalInt implements Animal{
 
   public void eat(){
      System.out.println("Mammal eats");
   }
 
   public void travel(){
      System.out.println("Mammal travels");
   } 
 
   public int noOfLegs(){
      return 0;
   }
 
   public static void main(String args[]){
      test m = new test();
      m.eat();
      m.travel();
   }
}

运行结果如下:

三、抽象类与接口的区别

 

posted @ 2019-08-04 21:01  黎先生  阅读(281)  评论(0编辑  收藏  举报