日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

abstract类中不可以有private的成员_别再说你不懂java面向对象了,阿里P7大佬一次性给你讲的明明白白

發布時間:2025/3/19 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 abstract类中不可以有private的成员_别再说你不懂java面向对象了,阿里P7大佬一次性给你讲的明明白白 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

面向對象在百度百科中是這樣解釋的:“面向對象是一種對現實世界理解和抽象的方法,是計算機編程技術發展到一定階段后的產物”。說的好像很流弊的樣子,看看就行。

包的認識

1.1:包的概念包是組織、整合類的一種方式其目的在于保證使用類的唯一性(同一個包中,里面所包含的類名是唯一的)比如在包A中定義了一個Test類,在包B中也定義了一個Test類,那么當使用A中的Test類時便導入包A調用A中的Test類(A.Test),以此保證類的唯一性。

1.2:導入包中的類Java中有很多現成的包供我們使用,使用這些包的方式有兩種

public class TestDemo { public static void main(String[] args) { java.util.Date time = new java.util.Date(); //使用 util 包中的Date類創建一個對象 System.out.println(time.getTime()); //調用該對象的 getTime 方法,獲得一個毫秒級別的時間戳 }}

上述代碼中,util 就是一個包,Date就是該包中的一個類,使用時用 java.包名.類名 使用

import java.util.Date;public class TestDemo { public static void main(String[] args) { Date time = new Date(); System.out.println(time.getTime()); }

第一個代碼每次使用類時都要加包的前綴,太過麻煩,因此還可使用第二種方式,在代碼最開頭使用 import 關鍵字導入需要的包,這樣就可以像使用自己定義的類一樣,直接用類名創建對象當同時需要同一個包中的多個類是,可以用 import.java.包名.* 的方式導入包,這樣就可以使用該包下的所有類(但建議不要這么使用,否則當導入多個包時還是會出現類名重復的現象)。

1.3:靜態導入包中除了類的普通方法外,還有一些靜態方法,使用這些方法時,可以使用 import static 的方式導入包中的靜態字段和方法,無需創建對象直接使用

import static java.lang.Math.*;public class TestDemo { public static void main(String[] args) { double x = 10.5; double y = 3.0; double result = sqrt(pow(x,y)+pow(x,y)); System.out.println(result); }

1.4:自定義類放入包中基本規則

  • 在文件的最上方加一個 package 語句指定該代碼在哪個包中
  • 包名盡量指定成唯一名字,防止多文件間沖突
  • 包名和代碼路徑相匹配
  • 如果一個類沒有 package 語句,則該類會被放到默認包中

1.5:包的訪問權限控制如果某個成員不包含 public 和 private 關鍵字,此時這個成員可以被包中的其他類使用,但不能在包外部類中使用

1.6:常見的系統包1、java.lang:系統常用基礎類(String,Object),jdk1.1以后自動導入2、java.lang.reflect: java 反射編程包3、java.net:進行網絡編程開發包4、java.sql:進行數據庫開發的支持包。5、java.util:是java提供的工具程序包。(集合類等)6、java.io:I/O編程開發包。

繼承

2.1 概念:當創建多個類時發現這些類之間存在一定的關聯關系,則可以創建一個父類擁有這些類的相同屬性和方法,讓這些類繼承與父類,來提高效率,達到代碼重用的效果。此時被繼承的類我們成為 父類、基類或者超類,而繼承的類我們稱為子類或者派生類,子類會繼承父類除構造方法外的其他所有東西。2.2 語法規則:class 子類 extend 父類{

}

  • 子類使用 extend 關鍵字繼承父類
  • Java中一個子類只能繼承一個父類
  • 子類會繼承父類的所有 public 的字段和方法
  • 對于父類的 private 的字段和方法,子類無法訪問
  • 子類實例中也包含父類實例,可使用 super 關鍵字得到父類的引用
class Animal{ public String name;//父類的name必須為 public 否則子類將無法訪問 public Animal(String name) { this.name = name; } public void eat(String food){ System.out.println(this.name+"吃"+food); }}class Dog extends Animal{ public Dog(String name){ super(name); }}class Bird extends Animal{ public Bird(String name){ super(name); } public void fly(){ System.out.println(this.name+"正在飛"); }}public class TestDemo { public static void main(String[] args) { Dog dog = new Dog("旺旺"); dog.eat("骨頭"); Bird bird = new Bird("啾啾"); bird.eat("米粒"); bird.fly(); }

2.3、protected關鍵字上述代碼中,如果將父類的 name 設為 private子類將無法訪問,但設為 public 又違背了封裝的規則,此時就需要用到 protect 關鍵字

  • 對于其他類的調用者來說,被 protect 修飾的字段和方法是不能被訪問的
  • 但對于 該類的子類同一個包下的其他類 來說,被 protect 修飾的字段和方法是可以被訪問的

小結:Java中對字段和方法共有四種訪問權限

  • private:只能在類內部訪問,內外部一律不行
  • 默認:在類內部能訪問,同一個包中的類也可以訪問
  • protect:在類內部能訪問,且在其子類和同一個包中的類也可以訪問
  • public:類內部和類的調用者都能訪問

2.4、final關鍵字final 可以修飾一個變量或者字段,用來表示常量final 也惡意修飾一個類,用來表現該類不能被繼承組合:即一個類中對另一個類的嵌套,在一個類中實例另一個類,達到代碼重用的效果

多態

3.1、向上轉型:如上代碼,創建一個 Bird 的對象可以寫成

Bird bird = new Bird();

也可以寫成

Bird bird = new Bird();Animal bird2 = bird;Animal bird3 = new Bird();

此時bird2、bird3是一個父類(Animal)的引用,指向子類(bird)的實例,這稱為向上轉型。向上轉型發生的時機:

  • 直接賦值(即上述代碼演示)
  • 方法傳參
  • 方法返回

方法傳參:

public static void main(String[] args) { Bird bird = new Bird("啾啾"); feed(bird);}public static void feed(Animal animal){ animal.eat("谷子");}

此時形參的類型是 Animal(父類) ,實際上是對應到 Bird(子類)的實例

方法返回:

public static void main(String[] args) { findAnimal().eat("谷子");}public static Animal findAnimal(){ Bird bird = new Bird("啾啾"); return bird;}

方法 findAnimal 返回值是 Animal 的一個引用,但實際指向 Bird 的一個實例

3.2:動態綁定子類和父類出現同名方法時發生

class Animal{ public String name; public Animal(String name) { this.name = name; } public void eat(String food){ System.out.println("我是一只小動物"); System.out.println(this.name+"正在吃"+food); }}class Bird extends Animal{ public Bird(String name){ super(name); } public void eat(String food){ System.out.println("我是一只小鳥"); System.out.println(this.name+"正在吃"+food); } public void fly(){ System.out.println(this.name+"正在飛"); }}public class TestDemo { public static void main(String[] args) { Animal animal1 = new Animal("動物"); Animal animal2 = new Bird("小鳥"); animal1.eat("谷子"); animal2.eat("谷子"); }

執行以上代碼我們發現:

  • animal1 和 animal2 雖然都是 Animal 類型的引用,但animal1指向 Animal 實例的對象,animal2指向 Bird 實例的對象
  • 對 animal1 和 animal2 分別調用eat方法,發現 animal1 調用的是父類的方法,animal2 調用的是子類的方法

在Java中,調用某個方法,究竟執行哪段代碼(是父類方法還是子類),取決于看這個引用指向的對象是父類對象還是子類對象,這個過程是在運行時才決定的,因此成為動態綁定父類引用,引用子類對象時,只能訪問自己特有的,不能訪問子類獨有的

3.3、重寫對于上述代碼,父類和子類的eat方法來說,就構成了重寫重寫的注意事項:

  • 普通方法可以重寫,static 修飾的方法不能重寫
  • 重寫中子類的訪問權限不能低于父類的訪問權限
  • 重寫和重載不同

重寫和重載的區別

1.要求不同重載:a.方法名相同 b.參數列表不同 c.返回值不做要求重寫:a.方法名相同 b.參數列表相同(參數類型和個數) c.返回值也要相同2.范圍不同重載:同一個類中重寫:繼承關系,不同類中3.限制重載:無限制重寫:子類中重寫的方法訪問權限不能低于父類的訪問權限

3.4、理解多態

class Shape { public void draw(){ }}class Circle extends Shape{ public void draw(){ System.out.println("畫一個圓圈○"); }}class Rectangle extends Shape{ public void draw(){ System.out.println("畫一個矩形□"); }}class Triangle extends Shape{ public void draw(){ System.out.println("畫一個三角△"); }}//================================================//================================================public class TestDemo { public static void main(String[] args) { Shape shape1 = new Circle(); Shape shape2 = new Rectangle(); Shape shape3 = new Triangle(); drawMap(shape1); drawMap(shape2); drawMap(shape3); } public static void drawMap(Shape shape){ shape.draw(); }

以上代碼,分割線以上是由類的實現者編寫的,分割線以下是由類的調用者編寫的當調用者編寫drawMap方法的時候(參數類型為父類Shape),并不關心當前shape引用指向哪個類型的實例,此時shape調用的draw方法只取決于shape指向的哪個類型的實例,以實現不同的表現形式,這種思想叫做多態。

3.5、向下轉型父類引用,引用子類對象稱為向上轉型;子類引用,引用父類對象稱為向下轉型。

class Animal{ public String name; public Animal(String name) { this.name = name; } public void eat(String food){ System.out.println("我是一只小動物"); System.out.println(this.name+"正在吃"+food); }}ass Bird extends Animal{ public Bird(String name){ super(name); } public void eat(String food){ System.out.println("我是一只小鳥"); System.out.println(this.name+"正在吃"+food); } public void fly(){ System.out.println(this.name+"正在飛"); }} public class TestDemo { public static void main(String[] args) { Animal animal = new Bird("啾啾"); animal.eat("谷子"); animal.fly();//執行該行代碼時,會報錯誤 }

編譯過程中 animal 的類型時 Animal ,編譯器編譯時根據類型只知道 animal 中只有一個eat方法,找不到fly方法

  • 編譯器檢查存在哪些方法時候,看的是 Animal 類型
  • 執行時究竟執行父類方法還是子類方法,看的是 Bird 類型
    但很多時候為了讓向下轉型更安全,需要判斷一下 animal 是否指向 Bird 的引用,使用instanceof 關鍵字判斷
Animal animal = new Cat("小貓");if (animal instanceof Bird) {Bird bird = (Bird)animal;bird.fly();}

3.6、super關鍵字當在子類內部要調用父類方法時,就要用到 super 關鍵字super 表示獲取到父類實例的引用,其有兩種常用方法

一、使用 super 來調用父類的構造方法,super(參數)

public Bird(String name){ super(name);}

二、使用 super 來調用父類的普通方法,super.方法名(參數)

class Bird extends Animal{ public Bird(String name){ super(name); } public void eat(String food){ super.eat(food); System.out.println("我是一只小鳥"); System.out.println(this.name+"正在吃"+food); }}

上述代碼中個,如果直接調用eat方法,則被編譯器認為是調用子類的方法(同遞歸),想要調用父類方法則需要使用 super 關鍵字

this和super的區別:

1、概念this:訪問本類的屬性和方法super:訪問父類的屬性和方法2、查找范圍this:先查找本類,子類沒有再調用父類super:不查找本類,直接調用父類3、特殊this:表示當前對象的引用super:表現父類對象的引用

多態存在的意義就在于,讓調用者不必關注對象的具體類型,降低用戶的使用成本

4、抽象類

4.1語法規則類似于之前代碼的父類 Shape 中的draw方法,其中并沒有實際工作,而由其子類重新該方法實現,那么像這種沒有實際工作的方法我們就可以用 abstract 關鍵字修飾把它設計成一個抽象方法,而包含抽象方法的類我們就稱為抽象類

abstract class Shape { abstract public void draw();}
  • 在draw方法前加一個 abstract 修飾表示該方法是抽象方法,抽象方法沒有方法體
  • 對于包含抽象方法的類,class 前必須加一個 abstract 關鍵字表示是抽象類

注意事項:

  • 抽象類不能直接實例
  • 抽象方法的訪問權限不能是private
  • 抽象類中可以包含其他非抽象方法,也可以包含字段,和普通方法一樣,可以被重新可以被調用

4.2抽象類的作用抽象類的意義在于為了被繼承抽象類本身不能實例化,想要使用,必須創建該抽象類的子類,在子類中重寫抽象方法使用抽象類相當于多了一重編譯器的檢驗(對于抽象了來說,如果繼承的子類不重寫父類的抽象方法,則會報錯)

5、接口

接口是比抽象類還抽象,接口只包含抽象方法,其字段也只能包含靜態常量

interface IShape{ abstract public void draw();}class Circle implements Shape{ @Override public void draw() { System.out.println(); }}
  • 用 interface 定義一個接口
  • 接口中的方法只能是抽象方法,所以可以省略 abstract
  • 并且接口中的方法只能是 public ,所以可以省略
  • Circle 用 implement 來實現接口
  • 在調用的時候同樣可以創建一個接口的引用,對應到一個子類的實例
  • 接口不能被單獨實例化

在Java中一個類只能繼承一個父類,但同時可以實現多個接口

class Animal{ public String name; public Animal(String name){ this.name = name; }}interface IFlying{ void fly();}interface IRunning{ void run();}interface ISwimming{ void swim();}class Dog extends Animal implements IRunning{ public Dog(String name){ super(name); } @Override public void run() { System.out.println(this.name+"正在跑步"); }}class Frog extends Animal implements IRunning,ISwimming{ public Frog(String name){ super(name); } @Override public void run() { System.out.println(this.name+"正在跑步"); } @Override public void swim() { System.out.println(this.name+"正在游泳"); }}class Duck extends Animal implements IRunning,ISwimming,IFlying{ public Duck(String name){ super(name); } @Override public void fly() { System.out.println(this.name+"正在飛"); } @Override public void run() { System.out.println(this.name+"正在游泳"); } @Override public void swim() { System.out.println(this.name+"正在游泳"); }}public class TestDemo { public static void main(String[] args) { Dog dog = new Dog("汪汪"); Frog frog = new Frog("呱呱"); Duck duck = new Duck("嘎嘎"); dog.run(); frog.run(); frog.swim(); duck.fly(); duck.run(); }}

接口使用實例——給對象數組排序創建一個學生類

class Students implements Comparable{ private String name; private int score; public Students(String name, int score) { this.name = name; this.score = score; } @Override public String toString() { return "Students{" + "name='" + name + ''' + ", score=" + score + '}'; } @Override public int compareTo(Object o) { Students s = (Students)o; if(s.score > ((Students) o).score){ return 1; }else if(s.score == ((Students) o).score){ return 0; }else{ return -1; } }}

在 sort 方法中會自動調用 compareTo 方法.compareTo 的參數是 Object,其實傳入的就是Students類型的對象,然后比較當前對象和參數對象的大小關系

接口間的承接一個接口可以承接另一個接口,達到復用效果,使用 extends 關鍵字接口間承接相當于把多個接口憑借在一起

Clonable 接口和深拷貝Object 類中存在一個 clone 方法,調用這個方法可以創建一個對象的“拷貝”,但是想要合法的調用clone方法,必須先要實現 Clonable 接口,否則就會拋出 CloneNotSupportedException 異常

class Person implements Cloneable{ public String name; public Person(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "Person{" + "name='" + name + ''' + '}'; }}public class TestDemo { public static void main(String[] args) throws CloneNotSupportedException { Person person1 = new Person("小明"); Person person2 = (Person) person1.clone(); person2.name = "小紅"; System.out.println(person1); System.out.println(person2); }}

如下代碼即深拷貝:

class Money implements Cloneable{ public int m=10; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }}class Person implements Cloneable{ public String name; public Money money ; public Person(String name) { this.name = name; this.money = new Money(); } @Override protected Object clone() throws CloneNotSupportedException { Person person = (Person) super.clone(); person.money = (Money) this.money.clone(); return person; } @Override public String toString() { return "Person{" + "name='" + name + ''' + ", money=" + money.m + '}'; }}public class TestDemo { public static void main(String[] args) throws CloneNotSupportedException { Person person1 = new Person("小明"); Person person2 = (Person) person1.clone(); person2.name = "小紅"; person2.money.m = 15; System.out.println(person1); System.out.println(person2); }}

總結

  • 抽象類和接口都是Java中多態的常見使用方法,但兩者又有區別
    最核心區別:抽象類可以包含普通方法和普通字段,可以被子類直接使用,而接口中只有抽象方法,實現該接口的類必須重寫所有抽象方法

最后

感謝你看到這里,看完有什么的不懂的可以在評論區問我,覺得文章對你有幫助的話記得給我點個贊,每天都會分享java相關技術文章或行業資訊,歡迎大家關注和轉發文章!

總結

以上是生活随笔為你收集整理的abstract类中不可以有private的成员_别再说你不懂java面向对象了,阿里P7大佬一次性给你讲的明明白白的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。