抽象類、密封類、介面
抽象類
-
抽象類 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中元素就會指向兩個地址,即深拷貝,下面的圖可以輔助理解