日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

面向对象——多态,抽象类,接口(二)

發(fā)布時間:2025/3/20 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面向对象——多态,抽象类,接口(二) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

前言:

多態(tài)

1.1 向下轉型(了解)

1.2 instanceof關鍵字

1.3 多態(tài)(理解)

1.4 多態(tài)的好處

抽象類

2.1 abstract關鍵字

2.2 語法規(guī)則

接口(重點)

3.1 語法規(guī)則

3.2?實現(xiàn)多個接口

3.4 接口與接口之間的關系

3.5 接口的好處

3.6 接口與抽象類的區(qū)別(要點)

接口常用實例

4.1 comparable接口

4.2 comparator接口

4.3 clonable接口和深拷貝

4.3.1 淺拷貝

4.3.2 深拷貝與clonable接口

4.3.3 clonable使用要點:

前言:

? ? ? ? 本篇文章主要講述對于包,接口,以及多態(tài)的理解,以及一些常用接口的了解,如果對于你有所幫助或者啟發(fā),不要忘記給作者點個贊哦!

多態(tài)

1.1 向下轉型(了解)

在前面一篇文章我們介紹了什么是向上轉型,向下轉型就是用子類的引用去引用父類引用所指的該子類對象,但是這個時候就必須的要進行強轉,因為這個時候是要父類的引用被子類的引用所引用,接下來我們可以通過一個代碼來理解一下

animal animal=new bird("fja",20);bird bird=(bird) animal;

此時就是子類的引用引用了父類引用所指的該子類對象,其實向下轉型還是不安全的,之前我們向上轉型中,父類引用子類,可以理解為子類是屬于父類的一種,而這里不能說父類是子類的一種。

1.2 instanceof關鍵字

對于向下轉型,我們可以采取利用instanceof關鍵字來判斷父類引用是否是子類的一個實例,具體用法如下

animal animal=new dog("fja",20);if (animal instanceof dog){System.out.println(333);}

如果animal引用的是dog的一個子類對象,就會執(zhí)行if語句里面的內(nèi)容,反之就不會執(zhí)行if語句里面的內(nèi)容,這樣子可以讓向下轉型更加安全的實現(xiàn)。

1.3 多態(tài)(理解)

對于多態(tài)我們可以結合一段代碼來進行理解什么是多態(tài)!

class shape{public void draw(){} } class rect extends shape{@Overridepublic void draw() {System.out.println("(●ˇ?ˇ●)");} } class small extends shape{@Overridepublic void draw() {System.out.println("small");} } public class test {public static void func(shape shape){shape.draw();}public static void main(String[] args) {rect rect=new rect();func(rect);small small=new small();func(small)} }

在這段代碼中我們定義了一個shape類里面的draw方法可以幫助我們打印出不同的形狀,我們結合之前所講的動態(tài)綁定,繼承,就可以來實現(xiàn)通過定義一個父類來實現(xiàn)打印不同的形狀,在這里我們可以了解到,在調(diào)用函數(shù)中,我們不用關注shape引用了那個類型的實例。也就是說通過一個父類shape的引用,來調(diào)用同一個方法,表現(xiàn)出來的形式有不同(與shape對應的實例有關),這樣的一個行為就被稱為是多態(tài)。

1.4 多態(tài)的好處

之前我們學過private封裝,封裝的好處就是讓類的調(diào)用者不需要知道類的實現(xiàn)細節(jié),那么此時多態(tài)的作用就是讓類的調(diào)用者不需要知道這個類的是什么類型,只需要這個對象的某個方法就可以了,這樣就讓類的調(diào)用者對類的使用成本進一步降低。

抽象類

2.1 abstract關鍵字

在多態(tài)中,我們發(fā)現(xiàn)通過動態(tài)綁定,父類中的方法是沒有被執(zhí)行的,那么這個時候我們可以通過abstract關鍵字將該方法變?yōu)槌橄蠓椒?#xff0c;那么包含抽象方法的類就被稱為抽象類。

abstract class shape{abstract public void draw(); }

2.2 語法規(guī)則

1 不能通過關鍵字new來實例化抽象類本身,但是可以發(fā)生向上轉型

2 抽象類最大的作用是被繼承

3 抽象類不能被final修飾,被final修飾的類是不能被繼承的

4 抽象類中也是可以包含字段與普通方法

5 一個普通類繼承了抽象類,那么這個普通類就需要重寫抽象類里面的全部抽象方法

6? 若一個抽象類A,繼承了一個抽象類B,抽象類A可以不重寫抽象類B中的抽象方法,此時若有一個普通類C,繼承了抽象類A,那么此時就需要重寫抽象類A與B中所有的抽象方法。

接口(重點)

3.1 語法規(guī)則

1 在抽象類的基礎上(可以理解為是抽象類的plus版本),我們利用interface關鍵字去定義一個接口,abstract public在接口是可以省略的,與抽象類一樣,接口也是不能被實例化的。

interface shape{abstract public void draw(); }

2 接口中不能含有普通方法與字段(如果要寫入普通方法,可以在普通方法前用關鍵字default修飾,表示為這個接口的默認方法)

3 接口中的成員變量都是被public static final(可以被省略)修飾的,并且都要被賦予初值

4 當一個類繼承了接口,就要重寫該接口中的所有抽象方法

5 接口的實現(xiàn)(implements關鍵字)

我們通過implements關鍵字來實現(xiàn)一個接口

interface shape{abstract public void draw(); } class cloud implements shape{@Overridepublic void draw() {System.out.println("這是一個接口實現(xiàn)");} } public class test {public static void main(String[] args) {shape shape=new cloud();shape.draw();} }

我們通過定義了一個cloud,通過關鍵字implements實現(xiàn)接口shape

6 當一個類實現(xiàn)了該接口,那么重寫該接口的抽象方法前一定要加上public

?接口中可以省略,但是重寫時可不能不寫,否則是包訪問權限,就比接口中的訪問權限就要小了。

3.2?實現(xiàn)多個接口

interface Is{abstract public void eat(); } interface shape{abstract public void draw(); } class cloud implements shape,Is{@Overridepublic void draw() {System.out.println("這是一個接口實現(xiàn)");}@Overridepublic void eat() {System.out.println("實現(xiàn)多個接口!");} } public class test {public static void main(String[] args) {shape shape=new cloud();shape.draw();} }

通過代碼我們可以知道一個類可以實現(xiàn)多個接口(本例子就列舉了兩個接口,其實可以多個接口),但要把每個接口的抽象方法要重寫,并且接口之間用逗號隔開。

3.4 接口與接口之間的關系

interface Irunning{abstract public void run(); } interface Iwalk{abstract public void walk(); } interface IC extends Irunning{abstract public void pdd(); }

從代碼中我們可以知道,接口與接口之間是通過extends關鍵字來表示兩個接口之間的關系,此時這里的extends不是繼承的意思,而表示拓展的意思,一個接口可以拓展另一個接口,而實現(xiàn)兩個接口的功能(如果要拓展多個接口,需要用逗號隔開)

3.5 接口的好處

1 彌補java中單繼承的缺點,因為可以擴展多個接口,那么我們可以通過繼承一個父類,利用implement關鍵字實現(xiàn)多個接口,從而實現(xiàn)更多的功能

2 多態(tài)能夠讓程序猿不必關注類的類型,那么接口就是讓程序猿不必關注類的類型,而是關注類所能實現(xiàn)的功能

例如:

我們先創(chuàng)建三個接口,去實現(xiàn)跑,游,飛三種功能

interface Irun{void run(); } interface Iswim{void swim(); } interface Ifly{void fly(); }

我們在定義一個父類animal

class Animal{String name;public Animal(String name){this.name=name;} }

定義實現(xiàn)一個功能的

//定義一個跑的動物 class DOG extends Animal implements Irun{public DOG(String name) {super(name);}@Overridepublic void run() {System.out.println(name+"四條腿跑");} }

定義一個實現(xiàn)兩個功能的動物

//定義一個會跳回游的青蛙 class frog extends Animal implements Irun,Iswim{@Overridepublic void run() {System.out.println(name+"在跳");}@Overridepublic void swim() {System.out.println(name+"游泳");}public frog(String name) {super(name);} }

定義一個能滿足三種功能的動物

//定義能滿足這三個功能的動物 class Duck extends Animal implements Irun,Iswim,Ifly{@Overridepublic void run() {System.out.println(name+"跑");}@Overridepublic void swim() {System.out.println(name+"游泳");}@Overridepublic void fly() {System.out.println(name+"飛");}public Duck(String name) {super(name);} }

在這里我們就可以看到,我們可以通過繼承一個類,實現(xiàn)多種接口,從而實現(xiàn)更多的功能,彌補了java中單繼承的缺陷。從這里也可以看出接口所要表達的含義就是:具有xxx特性

我們在這個基礎上,可以實現(xiàn)一個方法專門用于跑

public static void fun(Irun Irun){Irun.run();}

在這個方法的內(nèi)部我們不關心是什么類型,只要所給的參數(shù)會跑就行

public class node {public static void fun(Irun Irun){Irun.run();}public static void main(String[] args) {DOG DOG=new DOG("狗");fun(DOG);} }

接口的可擴展性非常強,只要一個類實現(xiàn)了該接口,就能通過該方法來實現(xiàn),請看下列代碼

lass Robot implements Irun { private String name; public Robot(String name) { this.name = name; } @Override public void run() { System.out.println(this.name + "正在用輪子跑"); } } Robot robot = new Robot("機器人"); fun(robot);

只要是實現(xiàn)了Irun這個接口,就可以通過實現(xiàn)方法,來實現(xiàn)該類的功能。

3.6 接口與抽象類的區(qū)別(要點)

核心區(qū)別:抽象類中是可以包含字段與普通方法的,方法與字段是可以直接被子類使用的(不需要重寫),接口中不含有普通方法,子類必須重寫接口中包含的所有抽象方法

圖解區(qū)別

接口常用實例

4.1 comparable接口

在java中,我們在數(shù)組中就學過了Arrays.sort()對一個整數(shù)類型的數(shù)組進行排序,那么對于在實際處理業(yè)務,有些時候排序需要我們指定一個指標進行排序,這個時候就要用到我們java中自帶的comparable接口

class Student implements Comparable<Student>{public String name;public int age;public double score;//這里的this是誰調(diào)用了compareTo方法誰就是@Overridepublic int compareTo(Student o) {//return this.age-o.age;//通過年齡進行比較//return (int)(this.score-o.score);//通過分數(shù)進行比較return this.name.compareTo(o.name);//甚至可以通過名字進行排序}public Student(String name, int age, double score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';} } public class demo {public static void main(String[] args) {Student student=new Student("haha",24,55);Student student1=new Student("heihei",20,89);System.out.println(student.compareTo(student1));} }

我們甚至可以利用這個接口對更多個數(shù)組排序,實現(xiàn)這個接口之后,利用Arrays.sort()進行排序

public static void main(String[] args) {Student[] students =new Student[3];students[0]=new Student("zhan",21,98);students[1]=new Student("hehe",17,87);students[2]=new Student("keke",34,99);Arrays.sort(students);System.out.println(Arrays.toString(students));}

這個類存在一定的缺點,對于類的侵害性大,所以下面我們在介紹comparator接口

4.2 comparator接口

先創(chuàng)立一個學生類

class Student {public String name;public int age;public double score;public Student(String name, int age, double score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';} }

創(chuàng)立一個年齡比較器

class AgeComparator implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {return o1.age-o2.age;} }

創(chuàng)立一個分數(shù)比較器

//成績比較器 class ScoreComrarator implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {return (int)(o1.score-o2.score);} }

創(chuàng)立一個名字比較器

//名字比較器 class NameComparator implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {return o1.name.compareTo(o2.name);} }

做完上面幾步之后,我們基本就可以實現(xiàn)一個(年齡,成績,名字)來排序

比較分數(shù)

public class demo {public static void main1(String[] args) {Student student=new Student("haha",24,55);Student student1=new Student("heihei",20,89);ScoreComrarator scoreComrarator=new ScoreComrarator();scoreComrarator.compare(student1,student);} }

比較多個數(shù)組的一個成績

public class demo {public static void main(String[] args) {Student[] students =new Student[3];students[0]=new Student("zhan",21,98);students[1]=new Student("hehe",17,87);students[2]=new Student("keke",34,99);ScoreComrarator scoreComrarator=new ScoreComrarator();Arrays.sort(students,scoreComrarator);System.out.println(Arrays.toString(students));} }

4.3 clonable接口和深拷貝

4.3.1 淺拷貝

class people{public int age; } public class apple {public static void main(String[] args) {people people=new people();people people1=people;System.out.println(people);System.out.println(people1);} }

??也就是所淺拷貝就是簡單來理解就是會有兩個引用公用了一個對象。

4.3.2 深拷貝與clonable接口

class people implements Cloneable {public int age;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();} } public class apple {public static void main(String[] args)throws CloneNotSupportedException {people people=new people();people people1=(people) people.clone();System.out.println(people);System.out.println(people1);} }

?所謂的深拷貝簡單理解就是一個引用對應單獨一個對象

4.3.3 clonable使用要點:

1 clonable接口源碼是不包含任何抽象方法的,是一個空接口,對于這個空接口的作用就是表示當前類是可以被克隆的。

2 對于clone方法結合clonable我們必須要在實現(xiàn)接口中重寫方法。

3 由于clone源碼是一個object類,所以這里我們必須進行類型強轉。

4 實現(xiàn)clone接口中需要我們拋異常,這個在后續(xù)的學習中,我們會講解異常。

淺拷貝與深拷貝的詳細理解參考這篇文章:

Java深入理解深拷貝和淺拷貝區(qū)別_riemann_的博客-CSDN博客_java深拷貝和淺拷貝的區(qū)別

總結

以上是生活随笔為你收集整理的面向对象——多态,抽象类,接口(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。