1. 程式人生 > >java基礎-抽象類/介面

java基礎-抽象類/介面

抽象類:包含抽象方法的類叫抽象類。抽象方法由 abstract修飾。有抽象方法的類也必須由abstract修飾。

  • 抽象方法:在抽象類內部不給予實現。當有一個類,繼承了當前的抽象方法後需要實現。抽象方法不能被private修飾(修飾意味著不能被別的類繼承,而抽象方法又必須被繼承);如果不加訪問修飾符,那麼必須預設為public。
 abstract class Animal{
    public abstract void bark();//抽象方法
}
 abstract class Dog extends Animal{
    public Dog(){       //建構函式
    }
    public void bark(){  //實現基類的抽象方法。
        System.out.println();
    }
 }
 abstract class LittleDog extends Dog{
     {
         System.out.println("例項程式碼塊");
     }  
     public  void bark(){
         System.out.println("複寫基類");
     }
 }

  • 抽象類的派生類:

  • 如果是普通類,那麼必須實現抽象類的抽象方法。

  • 如果是抽象類,那麼可以不實現基類的抽象方法。

  • 注意:

  • 抽象類當中可以有非抽象方法;

  • 抽象類不能建立例項物件 。 new

  • 面試問題:抽象類和普通類的區別?

  • 抽象類不能被例項化。

  • 抽象方法必須是public/protected/或者不寫修飾

  • 抽象類被abstract修飾。

  • 抽象方法不能在抽象類當中實現。

密封類:被final所修飾的類就是密封類。

  • 注意:
  • 該類不能作用於基類,因為不能被繼承。
  • 就算派生類被final所修飾也不可以。(防止有意的派生,本來密封了結果又繼承基類,等於沒有密封)
  • 密封方法:不能被重寫。

介面

  • 由interface定義
  • 成員變數屬性:預設為public static final
  • 成員方法:預設為public abstract
interface A extends {
    public abstract void fun();
}
interface B{
    public static final int age=10;//接口裡面的成員必須初始化
    public abstract void fun2();
}
interface C extends  A,B{ // 介面只能繼承介面不能實現介面。且不能繼承抽象類。
    
}
  • 注意:介面和抽象類的區別

  • 介面內的方法必須不能被實現(不能有非抽象方法),而抽象類可以有部分非抽象方法。

  • 抽象類只能繼承一次,但介面可以被實現或者繼承多個(也就是說一個抽象類可以繼承一個抽象父類,但是一個介面可以使用關鍵字extends 繼承多個介面)。

  • 抽象類是對類整體的抽象,而介面是對行為進行抽象。

  • 抽象類當中方法和成員變數沒有明確的要求。但是抽象類當中的方法不能是private。

  • 在Java中繼承只是單繼承。介面是另類的多繼承。

  • implements實現介面A B 介面必須實現方法。

  • interface D extends A B可以不用實現AB介面方法。但是等效於D介面中有A B D中所有的抽象方法。

四個特殊介面:

  • Cloneable:實現Clonable介面需要重寫Object的Clone方法。

  • super.clone(),這個操作主要是來做一次bitwise copy( binary copy ),即淺拷貝,他會把原物件完整的拷貝過來包括其中的引用。這樣會帶來問題,如果裡面的某個屬性是個可變物件,那麼原來的物件改變,克隆的物件也跟著改變。所以在呼叫完super.clone()後,一般還需要重新拷貝可變物件。

class Money implements Cloneable{
    double money=10.0d;

    @Override //重寫Object的clone方法。
    protected Object clone() throws CloneNotSupportedException {  //丟擲異常
        return super.clone();//返回值為基類也就是Object
    }
}
class Person5 implements Cloneable{
    private String name;
    Money m;
    public Person5(String name ){ //建構函式;
        this.name=name;
        this.m=new Money();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
       Person5 person5=(Person5)super.clone();  //clone一個物件
       person5.m=(Money)this.m.clone(); //clone這個物件的m方法
       return person5;
        }
    }

class cloneAble2 {
    public static void main(String args []) throws CloneNotSupportedException {  //丟擲異常
        Person5 person5=new Person5("hahah"); //產生一個物件,
        Person5 person51=(Person5)person5.clone(); //clone一個物件
        System.out.println(person5.m.money);
        System.out.println(person51.m.money);
        person5.m.money=1000.0d; 
        System.out.println(person5.m.money);
        System.out.println(person51.m.money);
    }
  • 面試問題:Cloneable在原始碼中是空介面,標記介面。請問這個空介面的設計有什麼作用?
    標記這個類可以進行clone,如果不實現這個介面JVM 不能識別。
  • Comparable:排序介面,若一個類實現了Comparable介面,就意味著“該類支援排序“
import java.util.Arrays;

class Students implements Comparable<Students> {  
    private String name;
    private int age;
    private double score;
    public Students(String name,int age,double score){//建構函式
        this.name=name;
        this.age=age;
        this.score=score;
    }
     @Override  
    public String toString() {
        return "Students{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }

    @Override  //呼叫comparable裡的compareTo方法
    public int compareTo(Students o) {  //複寫comparable
        return name.compareTo(o.name);  //字串需要再次使用comparaTo方法。
        return age-o.age ;//整型直接減就好
    }
}
class a {
    public static void main(String[] args) {


        Students[] students = new Students[3]; //建立一個類型別的類陣列
        students[0] = new Students("gaobo", 48, 99.0);
        students[1] = new Students("aangzhuo", 28, 49.0);
        students[2] = new Students("yangliu", 18, 59.9);
        Arrays.sort(students); //排序 
        System.out.println(Arrays.toString(students));

  • Comparator:比較介面。Comparator是比較器,我們若需要控制某個類的次序,可以建立一個“該類的比較器”來進行排序。
class Student { 
    private String name;
    private int age;
    private double score;

    public Student(String name,int age,double score) {//建構函式
        this.name=name;
        this.age=age;
        this.score=score;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}
class cloneAble {
    public static void main(String[] args) {


        Student[] student = new Student[3];
        student[0] = new Student("gaobo", 48, 99.0);
        student[1] = new Student("aangzhuo", 28, 49.0);
        student[2] = new Student("yangliu", 18, 59.9);
        Arrays.sort(student,new Comparator<Student>(){   //在類外呼叫Arrays.sort 裡面的comparator 方法
                    @Override
                    public int compare(Student o1, Student o2) {
                        return  o1.getAge()-o2.getAge();
                        return (int)(o1.getScore()-o2.getScore());   //預設為int 型別,所以必須強轉。
                        return o1.getName().compareTo(o2.getName()); //字串排序需要用到comparaTo方法進行比較。
                    }
                });

        System.out.println(Arrays.toString(student));
    }
}
  • 面試問題:Comparable和Comparator區別?
  • Comparable:在類內部進行重寫。
  • Comparator:在類外直接呼叫。(Comparable相當於“內部比較器”,而Comparator相當於“外部比較器”。 )