<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
什麼是抽象類呢?在現實生活中,我們說“人類”,我們無法對應到具體某個人,同樣的,“動物類”、“圖形類”這些無法對映到具體的物件的類就是抽象類。
抽象類是普通類的超集,意思就是普通類有的抽象類也有,只是它比普通類多了一些抽象方法而已。這些抽象方法可以有一個,也可以有多個。
它存在的意義就是讓子類來覆寫它的抽象方法,抽象類和抽象方法的實現使用 abstract 關鍵字實現:
此時Sharp類就是抽象類,可以看到它的圖示和普通類都有所不同。
範例:
public abstract void print();
抽象方法所在的類一定是抽象類,抽象方法只有方法宣告,沒有方法體{}
注意區分沒有方法體和方法體為空的情況
public abstract void print();//這是沒有方法體
public abstract void print(){ } //這是方法體為空,它是普通方法
1.抽象類無法直接範例化物件。例如上面的 Sharp 類,Sharp sharp = new Sharp();//這是錯誤的
2.子類繼承抽象類,必須覆寫抽象類中的所有抽象方法(前提是子類是普通類)
Triangle是一個普通類,此時沒覆寫方法就報錯了,這時我們使用alt + enter 快捷鍵,點選第一行,再點選ok,就覆寫了父類別的抽象方法
但是當子類依然是抽象類時,可以選擇不覆寫抽象方法
3.final 和 abstract 不能同時使用、private 和 abstract 不能同時使用
抽象類存在的最大意義就是被繼承,而且它仍然滿足繼承關係的 is a 原則
abstract class Person
class Chinese extends Person √
class Dog extends Person × //因為Dog not is a Person
同時抽象類任然受到單繼承的侷限,此時我們就引出了介面來打破這兩個侷限
Java使用 interface 關鍵字定義介面,介面中只有全域性常數和抽象方法(JDK之前)JDK8擴充套件了default方法。子類使用 implements 實現介面
一般介面的命名使用大寫 ' I ' 字母開頭,子類命名以 Impl 結尾
全域性常數:
public static final int NUM = 10;
抽象方法:
public abstract String msg( );
1.介面中只有 public 許可權,且只有全域性常數和抽象方法,所以 abstract、static、final、public這些關鍵字在介面內部都可以省略
public interface IMassage { int NUM = 10;//全域性常數 String msg();//抽象方法 }
2.介面沒有單繼承限制,子類可以同時實現多個父介面,多個介面之間使用逗號分隔。此時子類必須實現父類別介面中所有的抽象方法
public interface IMassage { int NUM = 10;//全域性常數 String msg();//抽象方法 } interface INews{ void getNews(); } //子類 public class MessageImpl implements IMassage,INews{ public String msg() { return null; } public void getNews() { } }
介面可以使用 extends 繼承多個父介面,下面的範例若類要實現介面 C ,就必須覆寫 A、B、C中所有的抽象方法
interface A{ void testA(); } interface B{ void testB(); } interface C extends A,B{ }
3.介面依然不能直接範例化物件,需要通過向上轉型實現
public class MessageImpl implements IMassage,INews{ public String msg() { return "hello JAVA"; } public void getNews() { System.out.println("hello n~"); } public static void main(String[] args) { IMassage m = new MessageImpl(); System.out.println(m.msg()); } }
//輸出:hello JAVA
m只能呼叫msg方法,不能呼叫INews介面類定義的方法,需要用父類別間的相互轉換實現呼叫
INews n = (INews)m; n.getNews();
//輸出:hello n~
4.子類若既要繼承類又要實現介面,就先繼承,後實現介面
public class D extends A implements X,Y{ }
引入範例:使用排序方法比較Student類中的物件
public class Student { private String name; private int age; public Student(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "Student{" + "name=" + name+'''+ ",age="+ age + '}'; } public static void main(String[] args) { Student s1 = new Student("張三",18); Student s2 = new Student("李四",20); Student s3 = new Student("王五",30); Student[] students = {s3,s1,s2}; Arrays.sort(students); System.out.println(Arrays.toString(students)); } }
執行結果:
程式報錯,因為Student類是自定義型別,當使用Arrays.sort方法對自定義型別進行排序時,自定義型別需要實現 Comparable 才具有可比較的能力
因此我們將上述範例做如下改動:
public class Student implements Comparable<Student>{ private String name; private int age; public Student(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "Student{" + "name=" + name+'''+ ",age="+ age + '}'; } @Override public int compareTo(Student o) { if (this.age == o.age){ return 0; }else if (this.age < o.age){ return -1; } return 1; } public static void main(String[] args) { Student s1 = new Student("張三",18); Student s2 = new Student("李四",20); Student s3 = new Student("王五",30); Student[] students = {s3,s1,s2};//亂序放入陣列 Arrays.sort(students); System.out.println(Arrays.toString(students)); } }
//輸出結果:
[Student{name=張三',age=18}, Student{name=李四',age=20}, Student{name=王五',age=30}]
可以看到陣列按照年齡的升序排序,達到了預期效果。如果想要按照年齡降序排列,只需要修改 compareTo 方法中的一和負一
實現Comparable介面,必須覆寫它的compareTo方法,該方法返回的數位:
在程式中,克隆是指複製一個新的物件,而這個新物件的屬性值是從舊物件中拷貝過來的
Cloneable 介面是一個標記介面,本身沒有任何抽象方法,當一個類實現了 Cloneable 介面,就表示該類具備了克隆的能力,這個能力是JVM賦予的,要知道在堆上開闢空間和物件建立都由JVM實現。
我們需要覆寫 Object 類的 clone 方法,點選向上轉型的圖示我們就能看到 Object 提供的該方法
可以看到,clone 方法沒有方法體,用 native 關鍵字修飾,叫做本地方法,clone方法不是Java語言實現的,而是C++實現的,要知道JVM就是由C++實現的。所以本地方法就表示Java呼叫了C++的同名方法,此處只是方法宣告,具體的方法實現是在C++中。所以雖然它沒有方法體,但它並不是抽象方法。
這裡我們就能知道一個小知識點:沒有方法體的方法不一定就是抽象方法
程式碼範例:
public class Cat implements Cloneable{ private String name; @Override protected Cat clone() throws CloneNotSupportedException { return (Cat) super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { Cat c1 = new Cat(); c1.name = "喵喵"; Cat c2 = c1.clone(); System.out.println(c1 == c2); System.out.println(c2.name); } }
輸出結果:
可以看到,輸出 false表示c1和c2不是同一個地址,也就是說在堆上為c2開闢了一個新空間,將c1的值拷貝給了c2
我們先看一個範例:
class A{ int num; } public class B implements Cloneable{ A a = new A(); @Override protected B clone() throws CloneNotSupportedException { return (B)super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { B b1 = new B(); B b2 = b1.clone(); System.out.println(b1 == b2); System.out.println(b2.a.num); b1.a.num = 100; System.out.println(b2.a.num); } }
輸出:false
0
100
根據結果我們看到,將b1.a的值改為100後,b2.a也隨之變化,就是說b1.a 和 b2.a 指向了相同的物件
這就是淺拷貝,拷貝出的 b1 物件只是拷貝了 b1 自身, 而沒有拷貝內部包含的 a 物件. 此時 b1 和 b2 中包含的 a 參照仍然是指向同一個物件. 此時修改一邊, 另一邊也會發生改變.
我們將程式碼做如下修改:
class A implements Cloneable{ int num; @Override protected A clone() throws CloneNotSupportedException { return (A)super.clone(); } } public class B implements Cloneable{ A a = new A(); @Override protected B clone() throws CloneNotSupportedException { B b = new B(); b.a = a.clone(); return b; } public static void main(String[] args) throws CloneNotSupportedException { B b1 = new B(); B b2 = b1.clone(); System.out.println(b1 == b2); System.out.println(b2.a.num); b1.a.num = 100; System.out.println(b2.a.num); } }
結果:false
0
0
我們讓A類也實現克隆介面,可以看到b1.a的修改沒有影響b2.a,說明此時b1和b2內部包含的a物件也是不同的,這種拷貝就叫做深拷貝
在Java中,實現深拷貝的方式有兩種:一種是遞迴實現Cloneable,上述的例子就是遞迴實現的;另外一種就是通過序列化(Serializable 介面)來進行拷貝。這兩種方法現在已經不常用了,現在實現深拷貝是將物件轉為json字串
到此這篇關於Java抽象類和介面使用梳理的文章就介紹到這了,更多相關Java 抽象類內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45