1. 程式人生 > >抽象類、密封類、介面

抽象類、密封類、介面

抽象類

  • 抽象類 1.包含抽象方法的類,叫做抽象類。由abstract修飾。 2.抽象類當中:可以有非抽象方法。 3.抽象類不能建立例項物件。

  • 抽象方法 1.在抽象類內部不給予實現。當有一個類,繼承了當前的抽象類後,需要實現。 2.抽象方法不能被private修飾,如果不加訪問修飾限定符,預設為public。

  • 抽象類的派生類 1.如果是普通類,那麼必須實現抽象類的抽象方法。 2.如果是抽象類,可以不實現基類的抽象方法。

  • 抽象類和普通類的區別 1、抽象類不能被例項化。 2、抽象方法不能被private修飾。 3、抽象類被abstract修飾。 4、抽象方法不能在抽象類當中實現。

如下程式碼為抽象類的例子:

abstract class Animals {
    public abstract void bark();
}
//派生類為普通類,必須實現基類的抽象方法
class Cat extends Animals {
    public void bark() {
        System.out.println("Cat:喵~~喵~~喵~~");
    }
}

class Dog extends Animals {
    public void bark() {
        System.out.println("Dog:汪~~汪~~汪~~");
    }
} //派生類為抽象類,可以不實現基類的抽象方法 abstract class Pig extends Animals { public void fun() { System.out.println("abstract class Pig:fun()"); } } public class TestDemo5 { public static void main(String[] args) { Dog dog = new Dog(); dog.bark();//Dog:汪~~汪~~汪~~ Cat cat = new
Cat(); cat.bark();//Cat:喵~~喵~~喵~~ } }

密封類

  • 密封類 一個類被final修飾,稱為密封類,為了防止有意的派生
  • 密封方法 被final修飾的方法,不能被重寫
  • 使用時應注意 1.該類不能作為基類。 2.派生類被final所修飾,該類也不可以作為基類。

如下程式碼為密封類的例子:

final class Student {
    private String grade;
    private int id;
    private String name;

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }
}

介面

  • 介面

介面由interface定義 屬性預設修飾符為public static final 方法預設修飾符為public abstract 如:

interface One {
    public static final int COUNT = 1;//修飾符為預設的,只寫int COUNT即可
    public abstract void methods1();
}
  • 介面和抽象類的區別

1.介面內的方法,必須不能被實現,而抽象類可以存在非抽象方法。

2.抽象類只能繼承一次,但是介面可以被實現或者繼承多個。

a. 一個抽象類可以繼承一個抽象父類,但是一個介面可以使用關鍵字 extends繼承多個介面 b. 抽象類是對類整體的抽象 而介面是對行為(方法)進行抽象 c. 介面中的成員變數和成員方法預設為public static final 和public abstract d. 抽象類當中的方法和成員變數的修飾符沒有明確要求,但是抽象類當中的 方法不能用private修飾。

interface One {
    public static final int COUNT = 1;

    public abstract void methods1();
}

interface Two {
    void methods2();
}
//這樣寫新的介面可以不實現extends後接口的方法
interface Three extends One, Two {
    void methods3();
}
//實現介面Three
class Test implements Three {

    public void methods1() {
        System.out.println("One.methods1()");
    }

    public void methods2() {
        System.out.println("Two.methods2()");
    }

    public void methods3() {
        System.out.println("Three.methods3()");
    }
}
public class TestDemo5 {
    public static void main(String[] args) {
        Test test = new Test();
        test.methods1();//One.methods1()
        test.methods2();//Two.methods2()
        test.methods3();//Three.methods3()
        One one = test;
        one.methods1();//One.methods1()
        Two two = test;
        two.methods2();//Two.methods2()
        Three three = test;
        three.methods3();//Three.methods3()
    }
}
  • 三種介面

1.Comparator

在類外實現 int compare(T o1, T o2)方法

class Teacher {
    private int id;
    private String subject;
    private String name;

    public Teacher(int id, String subject, String name) {
        this.id = id;
        this.subject = subject;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", subject='" + subject + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

public class TestDemo4 {
    public static void main(String[] args) {
        Teacher[] teacher = new Teacher[3];
        teacher[0] = new Teacher(04, "History", "H.s");
        teacher[1] = new Teacher(02, "Math", "M.a");
        teacher[2] = new Teacher(03, "English", "E.n");
        System.out.println(Arrays.toString(teacher));
        System.out.println("========按姓名排序=========");
        Arrays.sort(teacher, new Comparator<Teacher>() {
            @Override
            public int compare(Teacher aa, Teacher bb) {     
                return aa.getName().compareTo(bb.getName());
            }
        });
        System.out.println(Arrays.toString(teacher));
        System.out.println("========按id排序=========");
        Arrays.sort(teacher, new Comparator<Teacher>() {
            @Override
            public int compare(Teacher aa, Teacher bb) {
                return (aa.getId() - bb.getId());
            }
        });
        System.out.println(Arrays.toString(teacher));
    }
}

輸出結果: 在這裡插入圖片描述

2.Comparable

在類內實現compareTo(T o)方法

class Teacher implements Comparable <Teacher>{
    private int id;
    private String subject;
    private String name;

    public Teacher(int id, String subject, String name) {
        this.id = id;
        this.subject = subject;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", subject='" + subject + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
    @Override
    public int compareTo(Teacher aa) {
        return subject.compareTo(aa.subject);
    }
}

public class TestDemo4 {
    public static void main(String[] args) {
        Teacher[] teacher = new Teacher[3];
        teacher[0] = new Teacher(04, "History", "H.s");
        teacher[1] = new Teacher(02, "Math", "M.a");
        teacher[2] = new Teacher(03, "English", "E.n");
        Arrays.sort(teacher);
        System.out.println(Arrays.toString(teacher));
    }
}

3.Clonable

public interface Cloneable {

}

此介面在原始碼中為空介面,空介面的作用是標記這個類可以進行clone,如果不實現這個介面JVM不能夠識別。

例項:

class Color implements Cloneable {
    String name;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Size implements Cloneable {
    Color color;

    public Size() {
        this.color = new Color();
    }

    //重寫Object的克隆方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Size size = (Size) super.clone();
        size.color = (Color) this.color.clone();
        return size;
    }
}

public class TestDemo4 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Size size = new Size();
        Size size1 = (Size) size.clone();
        System.out.println(size.color.name);
        System.out.println(size1.color.name);
        size1.color.name = "red";
        System.out.println(size.color.name);
        System.out.println(size1.color.name);
    }
}

這種clone方法為深拷貝,原因如下:

在重寫的clone()方法中有以下兩條語句: Size size = (Size) super.clone(); size.color = (Color) this.color.clone();

在例子中的程式碼中,第一條語句將size中的元素全部克隆到了size1中,但是Size類中只有指向Color的color,所以此時兩者指向的地址相同

第二條語句將color指向的地址也同樣複製了,所以size和size1中元素就會指向兩個地址,即深拷貝,下面的圖可以輔助理解 在這裡插入圖片描述