Java 抽象類 抽象方法 接口

 

#抽象類
在面向對象的概念中,全部的對象都是經過類來描繪的,可是反過來,並非全部的類都是用來描繪對象的,若是一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。
抽象類除了不能實例化對象以外,類的其它功能依然存在,成員變量、成員方法和構造方法的訪問方式和普通類同樣。
因爲抽象類不能實例化對象,因此抽象類必須被繼承,才能被使用。也是由於這個緣由,一般在設計階段決定要不要設計抽象類。
父類包含了子類集合的常見的方法,可是因爲父類自己是抽象的,因此不能使用這些方法。
在Java中抽象類表示的是一種繼承關係,一個類只能繼承一個抽象類,而一個類卻能夠實現多個接口。

/* 文件名 : Employee.java */
public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}



/* 文件名 : Salary.java */
public class Salary extends Employee
{
   private double salary; //Annual salary
   public Salary(String name, String address, int number, double
      salary)
   {
       super(name, address, number);
       setSalary(salary);
   }
   public void mailCheck()
   {
       System.out.println("Within mailCheck of Salary class ");
       System.out.println("Mailing check to " + getName()
       + " with salary " + salary);
   }
   public double getSalary()
   {
       return salary;
   }
   public void setSalary(double newSalary)
   {
       if(newSalary >= 0.0)
       {
          salary = newSalary;
       }
   }
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}



/* 文件名 : AbstractDemo.java */
public class AbstractDemo
{
   public static void main(String [] args)
   {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
 
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
 
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

輸出
Constructing an Employee
Constructing an Employee
Call mailCheck using  Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.






#抽象方法
若是你想設計這樣一個類,該類包含一個特別的成員方法,該方法的具體實現由它的子類肯定,那麼你能夠在父類中聲明該方法爲抽象方法。
Abstract 關鍵字一樣能夠用來聲明抽象方法,抽象方法只包含一個方法名,而沒有方法體。
抽象方法沒有定義,方法名後面直接跟一個分號,而不是花括號。

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   
   //其他代碼
}

抽象類纔有抽象方法。
繼承抽象方法的子類必須重寫該方法。不然,該子類也必須聲明爲抽象類。
最終,必須有子類實現該抽象方法,不然,從最初的父類到最終的子類都不能用來實例化對象。

1. 抽象類不能被實例化(初學者很容易犯的錯),若是被實例化,就會報錯,編譯沒法經過。只有抽象類的非抽象子類能夠建立對象。
2. 抽象類中不必定包含抽象方法,可是有抽象方法的類一定是抽象類。
3. 抽象類中的抽象方法只是聲明,不包含方法體,就是不給出方法的具體實現也就是方法的具體功能。
4. 構造方法,類方法(用 static 修飾的方法)不能聲明爲抽象方法。
5. 抽象類的子類必須給出抽象類中的抽象方法的具體實現,除非該子類也是抽象類。


/* 文件名 : Employee.java */
public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   //其他代碼
}


/* 文件名 : Salary.java */
public class Salary extends Employee
{
   private double salary; // Annual salary
  
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
 
   //其他代碼
}



#接口
本例定義接口AreaInterface,其中有靜態常量pai和求面積的抽象方法area()。類Circle和類Rectangle實現了AreaInterface接口,即爲接口中的抽象方法area()編寫了知足各自要求的方法體,分別求圓形和長方形的面積。

/* 文件名 : AreaInterface.java */
package jiekou;
public interface AreaInterface{
double pai=Math.PI;
double area();
}

/* 文件名 : Circle.java */
package jiekou;
public class Circle implements AreaInterface{
double r;
public Circle(double x){
r=x;
}
//實現接口中的抽象方法,求圓面積
public double area(){
return pai * r * r;
}
public String toString(){
return "圓:r="+r+"\tarea="+area();
}
}


/* 文件名 : Rectangle.java */
package jiekou;
public class Rectangle implements AreaInterface{
double x,y;
public Rectangle(double a,double b){
x=a;
y=b;
}
public double area()//實現接口中的抽象方法,求長方形面積
{
return x * y;
}
public String toString()
{
return "長方形:x="+x+";y="+y+"\t"
area=+area();
}
}


Java接口和Java抽象類最大的一個區別,就在於Java抽象類能夠提供某些方法的部分實現,而Java接口不能夠,這大概就是Java抽象類惟一的優勢吧,但這個優勢很是有用。若是向一個抽象類里加入一個新的具體方法時,那麼它全部的子類都一會兒都獲得了這個新方法,而Java接口作不到這一點,若是向一個Java接口裏加入一個新方法,全部實現這個接口的類就沒法成功經過編譯了,由於你必須讓每個類都再實現這個方法才行,這顯然是Java接口的缺點。
一個抽象類的實現只能由這個抽象類的子類給出,也就是說,這個實現處在抽象類所定義出的繼承的等級結構中,而因爲Java語言的單繼承性,因此抽象類做爲類型定義工具的效能大打折扣。在這一點上,Java接口的優點就出來了,任何一個實現了一個Java接口所規定的方法的類均可以具備這個接口的類型,而一個類能夠實現任意多個Java接口,從而這個類就有了多種類型。
不難看出,Java接口是定義混合類型的理想工具,混合類代表一個類不只僅具備某個主類型的行爲,並且具備其餘的次要行爲。
在語法上,抽象類和接口有着如下不一樣:
1.abstract class在Java語言中表示的是一種繼承關係,一個類只能使用一次繼承關係。可是,一個類卻能夠實現多個interface。 繼承抽象類使用的是extends關鍵字,實現接口使用的是implements關鍵字,繼承寫在前面,實現接口寫在後面。若是實現多個接口,中間用逗號分隔。例:
public class Main extends JApplet
public class Main implements Runnable
public class Main extends JApplet implements ActionListener
public class Main extends JApplet implements ActionListener, Runnable
2.在abstract class中能夠有本身的數據成員,也能夠有非abstract的成員方法,而在interface中,只可以有靜態的不能被修改的數據成員(也就是必須是static final的,不過在 interface中通常不定義數據成員),全部的成員方法都是abstract的。
3.abstract class和interface所反映出的設計理念不一樣。其實abstract class表示的是"is-a"關係,interface表示的是"like-a"關係。
4.實現接口的類必須實現其中的全部方法,繼承自抽象類的子類實現全部的抽象方法。抽象類中能夠有非抽象方法。接口中則不能有實現方法。
5.接口中定義的變量默認是public static final 型,且必須給其初值,因此實現類中不能從新定義,也不能改變其值。
6.抽象類中的變量默認具備 friendly權限,其值能夠在子類中從新定義,也能夠從新賦值。
7.接口中的方法默認都是 public abstract 類型的。



參考:
https://baike.baidu.com/item/java%E6%8E%A5%E5%8F%A3/4939170?noadapt=1
https://www.runoob.com/java/java-abstraction.html
相關文章
相關標籤/搜索