【詳識JAVA語言】面向對象程序三大特性之二:繼承

繼承

為什么需要繼承

Java中使用類對現實世界中實體來進行描述,類經過實例化之后的產物對象,則可以用來表示現實中的實體,但是 現實世界錯綜復雜,事物之間可能會存在一些關聯,那在設計程序是就需要考慮。

比如:狗和貓,它們都是一個動物。

使用Java語言來進行描述,就會設計出:

// Dog.javapublic class Dog{string name;int age;?oat weight;public void eat(){System.out.println(name + "正在吃飯");}public void sleep(){System.out.println(name + "正在睡覺");}void Bark(){System.out.println(name + "汪汪汪~~~");}}// Cat.Javapublic class Cat{string name;int age;?oat weight;public void eat(){System.out.println(name + "正在吃飯");}public void sleep() {System.out.println(name + "正在睡覺");}void mew(){System.out.println(name + "喵喵喵~~~");}}

通過觀察上述代碼會發現,貓和狗的類中存在大量重復,如下所示:

?

那能否將這些共性抽取呢?面向對象思想中提出了繼承的概念,專門用來進行共性抽取,實現代碼復用。?

繼承概念

繼承(inheritance)機制:是面向對象程序設計使代碼可以復用的最重要的手段,它允許程序員在保持原有類特性的基礎上進行擴展,增加新功能,這樣產生新的類,稱派生類

繼承呈現了面向對象程序設計的層次結構, 體現了 由簡單到復雜的認知過程。繼承主要解決的問題是:共性的抽取,實現代碼復用。

例如:狗和貓都是動物,那么我們就可以將共性的內容進行抽取,然后采用繼承的思想來達到共用。

上述圖示中,Dog和Cat都繼承了Animal類,其中:Animal類稱為父類/基類或超類,Dog和Cat可以稱為Animal的 子類/派生類,繼承之后,子類可以復用父類中成員,子類在實現時只需關心自己新增加的成員即可。

從繼承概念中可以看出繼承最大的作用就是:實現代碼復用,還有就是來實現多態(后序講)。?

繼承的語法

在Java中如果要表示類之間的繼承關系,需要借助extends關鍵字,具體如下:

修飾符 class 子類 extends 父類 {// ...}

對之前中場景使用繼承方式重新設計:

// Animal.javapublic class Animal{String name;int age;public void eat(){System.out.println(name + "正在吃飯");}public void sleep(){System.out.println(name + "正在睡覺");}}// Dog.javapublic class Dog extends Animal{void bark(){System.out.println(name + "汪汪汪~~~");} }// Cat.Javapublic class Cat extends Animal{void mew(){System.out.println(name + "喵喵喵~~~");} }// TestExtend.javapublic class TestExtend {public static void main(String[] args) {Dog dog = new Dog();// dog類中并沒有定義任何成員變量,name和age屬性肯定是從父類Animal中繼承下來的 System.out.println(dog.name);System.out.println(dog.age);// dog訪問的eat()和sleep()方法也是從Animal中繼承下來的dog.eat();dog.sleep();dog.bark();}}

注意:

1. 子類會將父類中的成員變量或者成員方法繼承到子類中了

2. 子類繼承父類之后,必須要新添加自己特有的成員,體現出與基類的不同,否則就沒有必要繼承了

父類成員訪問

在繼承體系中,子類將父類中的方法和字段繼承下來了,那在子類中能否直接訪問父類中繼承下來的成員呢?

子類中訪問父類的成員變量

1. 子類和父類不存在同名成員變量
public class Base { int a; int b; }public class Derived extends Base{int c; public void method(){a = 10; // 訪問從父類中繼承下來的ab = 20; // 訪問從父類中繼承下來的bc = 30; // 訪問子類自己的c }}
2. 子類和父類成員變量同名
public class Base { int a; int b; int c; }/ 
public class Derived extends Base{int a; // 與父類中成員a同名,且類型相同 char b; // 與父類中成員b同名,但類型不同public void method(){ // 訪問父類繼承的a,還是子類自己新增的a? // 訪問父類繼承的b,還是子類自己新增的b?a = 100;b = 101;c = 102;// 子類沒有c,訪問的肯定是從父類繼承下來的c // d = 103; // 編譯失敗,因為父類和子類都沒有定義成員變量b }}

在子類方法中 或者 通過子類對象訪問成員時:

如果訪問的成員變量子類中有,優先訪問自己的成員變量。

如果訪問的成員變量子類中無,則訪問父類繼承下來的,如果父類也沒有定義,則編譯報錯。

如果訪問的成員變量與父類中成員變量同名,則優先訪問自己的。

成員變量訪問遵循就近原則,自己有優先自己的,如果沒有則向父類中找。

子類中訪問父類的成員方法?

1. 成員方法名字不同
public class Base { 
public void methodA(){ System.out.println("Base中的methodA()"); } }public class Derived extends Base{ public void methodB(){System.out.println("Derived中的methodB()方法");}public void methodC(){ methodB(); // 訪問子類自己的methodB() methodA(); // 訪問父類繼承的methodA() // methodD(); // 編譯失敗,在整個繼承體系中沒有發現方法methodD() }}

總結:成員方法沒有同名時,在子類方法中或者通過子類對象訪問方法時,則優先訪問自己的,自己沒有時 再到父類中找,如果父類中也沒有則報錯。

2. 成員方法名字相同
public class Base {public void methodA(){ System.out.println("Base中的methodA()"); }public void methodB(){ System.out.println("Base中的methodB()"); }}public class Derived extends Base{ public void methodA(int a) {System.out.println("Derived中的method(int)方法");}public void methodB(){System.out.println("Derived中的methodB()方法");}public void methodC(){ methodA(); // 沒有傳參,訪問父類中的methodA() methodA(20); // 傳遞int參數,訪問子類中的methodA(int) methodB(); // 直接訪問,則永遠訪問到的都是子類中的methodB(),基類的無法訪問到 }}

【說明】

通過子類對象訪問父類與子類中不同名方法時,優先在子類中找,找到則訪問,否則在父類中找,找到 則訪問,否則編譯報錯。

通過派生類對象訪問父類與子類同名方法時,如果父類和子類同名方法的參數列表不同(重載),根據調用 方法適傳遞的參數選擇合適的方法訪問,如果沒有則報錯;

問題:如果子類中存在與父類中相同的成員時,那如何在子類中訪問父類相同名稱的成員呢?

super關鍵字?

由于設計不好,或者因場景需要,子類和父類中可能會存在相同名稱的成員,如果要在子類方法中訪問父類同名成 員時,該如何操作?直接訪問是無法做到的,Java提供了super關鍵字,該關鍵字主要作用:在子類方法中訪問父 類的成員

public class Base {int a;int b;public void methodA(){System.out.println("Base中的methodA()");}public void methodB(){System.out.println("Base中的methodB()");}}public class Derived extends Base{int a; // 與父類中成員變量同名且類型相同 char b;// 與父類中成員變量同名但類型不同// 與父類中methodA()構成重載public void methodA(int a) {System.out.println("Derived中的method()方法");}// 與基類中methodB()構成重寫(即原型一致,重寫后序詳細介紹)public void methodB(){System.out.println("Derived中的methodB()方法");}public void methodC(){// 對于同名的成員變量,直接訪問時,訪問的都是子類的a = 100; // 等價于: this.a = 100;b = 101; // 等價于: this.b = 101;// 注意:this是當前對象的引用// 訪問父類的成員變量時,需要借助super關鍵字// super是獲取到子類對象中從基類繼承下來的部分super.a = 200;super.b = 201;// 父類和子類中構成重載的方法,直接可以通過參數列表區分清訪問父類還是子類方法 methodA();// 沒有傳參,訪問父類中的methodA() methodA(20);// 傳遞int參數,訪問子類中的methodA(int)// 如果在子類中要訪問重寫的基類方法,則需要借助super關鍵字 methodB();// 直接訪問,則永遠訪問到的都是子類中的methodA(),基類的無法訪問到 super.methodB();// 訪問基類的methodB()}}

在子類方法中,如果想要明確訪問父類中成員時,借助super關鍵字即可。

【注意事項】

1. 只能在非靜態方法中使用

2. 在子類方法中,訪問父類的成員變量和方法。

子類構造方法

父子父子,先有父再有子,即:子類對象構造時,需要先調用基類構造方法,然后執行子類的構造方法。

public class Base {public Base(){ System.out.println("Base()");} }public class Derived extends Base{public Derived(){ // super(); // 注意子類構造方法中默認會調用基類的無參構造方法:super(), // 用戶沒有寫時,編譯器會自動添加,而且super()必須是子類構造方法中第一條語句, // 并且只能出現一次 System.out.println("Derived()"); }}public class Test { public static void main(String[] args) { Derived d = new Derived(); } }結果打印: Base() Derived()

?

在子類構造方法中,并沒有寫任何關于基類構造的代碼,但是在構造子類對象時,先執行基類的構造方法,然后執 行子類的構造方法,因為:子類對象中成員是有兩部分組成的,基類繼承下來的以及子類新增加的部分 。父子父子 肯定是先有父再有子,所以在構造子類對象時候 ,先要調用基類的構造方法,將從基類繼承下來的成員構造完整 ,然后再調用子類自己的構造方法,將子類自己新增加的成員初始化完整 。

注意:

1. 若父類顯式定義無參或者默認的構造方法,在子類構造方法第一行默認有隱含的super()調用,即調用基類構 造方法

2. 如果父類構造方法是帶有參數的,此時需要用戶為子類顯式定義構造方法,并在子類構造方法中選擇合適的 父類構造方法調用,否則編譯失敗。

3. 在子類構造方法中,super(...)調用父類構造時,必須是子類構造函數中第一條語句。

4. super(...)只能在子類構造方法中出現一次,并且不能和this同時出現

super和this

super和this都可以在成員方法中用來訪問:成員變量和調用其他的成員函數,都可以作為構造方法的第一條語句,那他們之間有什么區別呢?

【相同點】

1. 都是Java中的關鍵字

2. 只能在類的非靜態方法中使用,用來訪問非靜態成員方法和字段

3. 在構造方法中調用時,必須是構造方法中的第一條語句,并且不能同時存在

【不同點】

1. this是當前對象的引用,當前對象即調用實例方法的對象,super相當于是子類對象中從父類繼承下來部分成 員的引用

2. 在非靜態成員方法中,this用來訪問本類的方法和屬性,super用來訪問父類繼承下來的方法和屬性

3. 在構造方法中:this(...)用于調用本類構造方法,super(...)用于調用父類構造方法,兩種調用不能同時在構造 方法中出現

4. 構造方法中一定會存在super(...)的調用,用戶沒有寫編譯器也會增加,但是this(...)用戶不寫則沒有

再談初始化

?我們還記得之前講過的代碼塊嗎?我們簡單回顧一下幾個重要的代碼塊:實例代碼塊和靜態代碼塊。在沒有繼承關系時的執行順序。

class Person {public String name; public int age; public Person(String name, int age) {this.name = name;this.age = age;System.out.println("構造方法執行");}{System.out.println("實例代碼塊執行"); } static {System.out.println("靜態代碼塊執行"); }}public class TestDemo {public static void main(String[] args) { Person person1 = new Person("bit",10);System.out.println("============================");Person person2 = new Person("gaobo",20);}}

執行結果:

靜態代碼塊執行

實例代碼塊執行

構造方法執行

============================

實例代碼塊執行

構造方法執行

1. 靜態代碼塊先執行,并且只執行一次,在類加載階段執行

2. 當有對象創建時,才會執行實例代碼塊,實例代碼塊執行完成后,最后構造方法執行

【繼承關系上的執行順序】

class Person {public String name; public int age; public Person(String name, int age) {this.name = name;this.age = age;System.out.println("Person:構造方法執行"); } {System.out.println("Person:實例代碼塊執行"); } static {System.out.println("Person:靜態代碼塊執行"); }}class Student extends Person{public Student(String name,int age) { super(name,age); System.out.println("Student:構造方法執行"); }{System.out.println("Student:實例代碼塊執行");}static { System.out.println("Student:靜態代碼塊執行"); }}public class TestDemo4 {public static void main(String[] args) { Student student1 = new Student("張三",19);System.out.println("===========================");Student student2 = new Student("gaobo",20); }public static void main1(String[] args) { Person person1 = new Person("bit",10);System.out.println("============================");Person person2 = new Person("gaobo",20);}}

執行結果:

Person:靜態代碼塊執行

Student:靜態代碼塊執行

Person:實例代碼塊執行

Person:構造方法執行

Student:實例代碼塊執行

Student:構造方法執行

===========================

Person:實例代碼塊執行

Person:構造方法執行

Student:實例代碼塊執行

Student:構造方法執行

通過分析執行結果,得出以下結論:

1、父類靜態代碼塊優先于子類靜態代碼塊執行,且是最早執行

2、父類實例代碼塊和父類構造方法緊接著執行

3、子類的實例代碼塊和子類構造方法緊接著再執行

4、第二次實例化子類對象時,父類和子類的靜態代碼塊都將不會再執行

protected 關鍵字

在類和對象章節中,為了實現封裝特性,Java中引入了訪問限定符,主要限定:類或者類中成員能否在類外或者其 他包中被訪問。

那父類中不同訪問權限的成員,在子類中的可見性又是什么樣子的呢?

// 為了掩飾基類中不同訪問權限在子類中的可見性,為了簡單類B中就不設置成員方法了 // extend01包中 public class B {private int a;protected int b;public int c;int d; }// extend01包中 // 同一個包中的子類 public class D extends B{public void method(){ // super.a = 10; // 編譯報錯,父類private成員在相同包子類中不可見 super.b = 20; // 父類中protected成員在相同包子類中可以直接訪問 super.c = 30; // 父類中public成員在相同包子類中可以直接訪問 super.d = 40; // 父類中默認訪問權限修飾的成員在相同包子類中可以直接訪問 }}// extend02包中 // 不同包中的子類 public class C extends B { public void method(){// super.a = 10; // 編譯報錯,父類中private成員在不同包子類中不可見 super.b = 20; // 父類中protected修飾的成員在不同包子類中可以直接訪問 super.c = 30;// 父類中public修飾的成員在不同包子類中可以直接訪問//super.d = 40; // 父類中默認訪問權限修飾的成員在不同包子類中不能直接訪問}}// extend02包中 // 不同包中的類 public class TestC { public static void main(String[] args) {C c = new C();c.method(); // System.out.println(c.a); // 編譯報錯,父類中private成員在不同包其他類中不可見// System.out.println(c.b); // 父類中protected成員在不同包其他類中不能直接訪問System.out.println(c.c); // 父類中public成員在不同包其他類中可以直接訪問// System.out.println(c.d); // 父類中默認訪問權限修飾的成員在不同包其他類中不能直接訪問}}

注意:父類中private成員變量雖然在子類中不能直接訪問,但是也繼承到子類中了

什么時候下用哪一種呢?

我們希望類要盡量做到 "封裝", 即隱藏內部實現細節, 只暴露出 必要 的信息給類的調用者.

因此我們在使用的時候應該盡可能的使用 比較嚴格 的訪問權限. 例如如果一個方法能用 private, 就盡量不要 用 public.

另外, 還有一種 簡單粗暴 的做法: 將所有的字段設為 private, 將所有的方法設為 public. 不過這種方式屬于是 對訪問權限的濫用, 還是更希望同學們能寫代碼的時候認真思考, 該類提供的字段方法到底給 "誰" 使用(是類內 部自己用, 還是類的調用者使用, 還是子類使用).

繼承方式

在現實生活中,事物之間的關系是非常復雜,靈活多樣,比如:

?但在Java中只支持以下幾種繼承方式:???????

注意:Java中不支持多繼承。

時刻牢記, 我們寫的類是現實事物的抽象. 而我們真正在公司中所遇到的項目往往業務比較復雜, 可能會涉及到 一系列復雜的概念, 都需要我們使用代碼來表示, 所以我們真實項目中所寫的類也會有很多. 類之間的關系也會 更加復雜.

但是即使如此, 我們并不希望類之間的繼承層次太復雜. 一般我們不希望出現超過三層的繼承關系. ?如果繼承層 次太多, 就需要考慮對代碼進行重構了.

如果想從語法上進行限制繼承, 就可以使用 ?nal 關鍵字

?nal 關鍵字

??nal關鍵可以用來修飾變量、成員方法以及類。

1. 修飾變量或字段,表示常量(即不能修改)

?nal int a = 10;a = 20; // 編譯出錯

2. 修飾類:表示此類不能被繼承

?nal public class Animal { ...}public class Bird extends Animal { ...}// 編譯出錯 Error:(3, 27) java: 無法從最終com.bit.Animal進行繼

我們平時是用的 String 字符串類, 就是用 ?nal 修飾的, 不能被繼承.?

3. 修飾方法:表示該方法不能被重寫

后序介紹

繼承與組合

和繼承類似, 組合也是一種表達類之間關系的方式, 也是能夠達到代碼重用的效果。組合并沒有涉及到特殊的語法 (諸如 extends 這樣的關鍵字), 僅僅是將一個類的實例作為另外一個類的字段。

繼承表示對象之間是is-a的關系,比如:狗是動物,貓是動物

組合表示對象之間是has-a的關系,比如:汽車

汽車和其輪胎、發動機、方向盤、車載系統等的關系就應該是組合,因為汽車是有這些部件組成的。

// 輪胎類 class Tire{ // ...}// 發動機類 class Engine{ // ...}// 車載系統類 class VehicleSystem{ // ...}class Car{private Tire tire; // 可以復用輪胎中的屬性和方法 private Engine engine; // 可以復用發動機中的屬性和方法 private VehicleSystem vs; // 可以復用車載系統中的屬性和方法// ...}// 奔馳是汽車 class Benz extend Car{ // 將汽車中包含的:輪胎、發送機、車載系統全部繼承下來}

組合和繼承都可以實現代碼復用,應該使用繼承還是組合,需要根據應用場景來選擇,一般建議:能用組合盡量用組合。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717529.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717529.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717529.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

04.其他方案

其他方案 1.事務狀態表調??重試接收?冪等 介紹 調??維護?張事務狀態表(或者說事務?志、?志流?),在每次調?之前,落盤?條事務流?,?成?個全局的事務ID 事務開始之前的狀態是Begin,全部結束之…

Go語言進階篇——文件

文件的打開 文件的常見的兩種打開方式是基于os包所提供的兩個函數: func Open(name string) (*File,error) func OpenFile(name string flag int perm FileMode) (*File,error)相對于前者,OpenFile可以提供更加細致的操作,而前者就是對后者的一個簡單封…

碼垛工作站:食品生產企業的轉型助推器

在當今高度自動化的工業生產中,碼垛工作站的應用正逐漸成為一種趨勢。某食品生產企業在面臨市場競爭加劇、人工成本上升等多重壓力下,決定引入碼垛工作站,以期實現生產流程的升級與變革。 一、碼垛工作站引入背景 該企業主要從事休閑食品的…

Android 中的 LinearLayout 布局

在 Android 開發中,布局是至關重要的一部分,它決定了應用程序的界面結構和用戶體驗。LinearLayout 是 Android 中最常用的布局之一,它以線性方式排列子視圖,可以垂直或水平布局。在這篇博客中,我們將深入了解 LinearLa…

數據結構實現-棧和隊列

順序棧 #include <iostream> using namespace std; #define MaxSize 50//順序棧 template<typename ElemType> struct SqStack{ElemType data[MaxSize];int top; };//初始化 template<typename ElemType> void InitStack(SqStack<ElemType>&s){s.…

Postman和Jmeter的區別

1.用例組織方式不同 jmeter組織方式相對比較扁平&#xff0c;沒有工作空間的概念&#xff0c;直接就是測試計劃 postman組織方式會比較輕量級&#xff0c;只要是針對單個的HTTP請求 2.支持的接口類型與測試類型上 jmeter會更強大&#xff0c;可以支持REST、Soap等等&#xf…

Kotlin 協程遇見 Flow:打造更優雅的數據流處理

Kotlin Flow 是 Kotlin 協程庫中的一個組件&#xff0c;它提供了處理異步數據流的能力。Kotlin Flow 類似于 RxJava 中的 Observable&#xff0c;但它完全基于 Kotlin 協程設計&#xff0c;使得異步流的操作變得更加簡單和直觀。 Flow 是冷流&#xff08;cold stream&#xff…

【貪心算法】Leetcode 455.分發餅干 376. 擺動序列 53. 最大子數組和

【貪心算法】Leetcode 455 分發餅干 376. 擺動序列【規律很多】53. 最大子數組和 455 分發餅干局部最優推全局最優&#xff1a;盡量用大餅干去滿足大胃口的小朋友 376. 擺動序列【規律很多】思想&#xff1a;注意考慮一個坡度留首尾兩個點、平坡、首尾 53. 最大子數組和【好思想…

15.網絡游戲逆向分析與漏洞攻防-網絡通信數據包分析工具-發送通信數據包至分析工具

上一個內容&#xff1a;14.數據包分析工具界面與通信設計 碼云地址&#xff08;master 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/titan 碼云版本號&#xff1a;2d6491e3c51a1a7ab4da0ee6dc4cf566a80fd6e1 代碼下載地址&#xff0c;在 titan 目錄下&…

模版進階C++

非類型模版 之前我們寫的模版都是在不知道模版&#xff08;類&#xff09;中有的變量的類型是什么的時候&#xff0c;我們先用模版參數定義&#xff0c;當類實例化的時候在傳參確認 非類型模版&#xff1a;模版參數定義的時候也可以定義整型類型&#xff08;c20之后才支持其…

奇點云:SAFe框架下,我們對平臺軟件工程生產線做了4項改造

導讀&#xff1a; 客戶規模擴大&#xff0c;如何保證大數據軟件產品和服務質量始終如一&#xff1f;幾乎所有成長中的軟件廠商&#xff0c;尤其是需要通過私有化部署交付的廠商&#xff0c;都會面臨這個問題。正如《人月神話》中多次表明的&#xff0c;單純地增加人手、擴大團隊…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的植物病害檢測系統(Python+PySide6界面+訓練代碼)

摘要&#xff1a;開發高效的植物病害檢測系統對于提升農業生產效率和作物健康管理意義重大。本篇博客詳細闡述了如何運用深度學習技術構建一個植物病害檢測系統&#xff0c;并提供了完整的實現代碼。該系統基于先進的YOLOv8算法&#xff0c;對YOLOv7、YOLOv6、YOLOv5進行了性能…

考研數學——高數:微分方程

一、一階線性微分方程 兩種形式&#xff1a; 非齊次&#xff1a; 齊次&#xff1a; 推導過程 推導公式的過程一般由特殊到一般&#xff1a;所以先求解齊次方程的解 &#xff08;然后對等式兩邊同時積分&#xff09; 再來求非齊次方程的解&#xff0c;由…

【測開求職】2023秋招快手一面面經

已經過了百度測開三面,快手這個一面比百度的要難很多,可能也是遇到了比較嚴格的面試官,感覺其他面經沒有這么難。30分鐘實習,20分鐘算法題,20分鐘八股,沒有問項目。 實習 diff遇到了哪些痛點diff是全量還是增量一些字段的增加或者枚舉值的增加可以用diff測嗎有哪些自動化…

03-grafana的下拉列表選項制作-grafana的變量

一、準備環境 為了實現下拉列表篩選的樣例&#xff0c;我們監控兩個linux節點&#xff1b; 目前&#xff0c;我們已經有了一個節點了&#xff0c;再添加一個&#xff1b; 二、grafana的儀表盤變量 如果想給儀表盤自定義下拉列表&#xff0c;那么&#xff0c;需要設置變量&#…

線上問題——2021-12-27 父子線程共用線程池導致死鎖故障

一、事故現象 從早上6點開始edu-wings-admin的timer-task和mq就開始報警任務堆積&#xff0c;且數量持續上升&#xff0c;到6點50左右mq也開始告警&#xff0c;8點左右發現問題&#xff0c;開始排查&#xff0c;直到11點才找到問題&#xff0c;任務開始正常消費。 二、事故影響…

haproxy集成國密ssl功能[下]

上接[haproxy集成國密ssl功能上 4. 源碼修改解析 以下修改基本圍繞haproxy的ssl_sock.c進行修改來展開的,為了將整個實現邏輯能夠說明清楚,下述內容有部分可能就是直接摘抄haproxy的原有代碼沒有做任何修改,而大部分增加或者修改的內容則進行了特別的說明。 4.1 為bind指令…

基于springboot+vue的疾病防控綜合系統

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

計算機設計大賽 深度學習貓狗分類 - python opencv cnn

文章目錄 0 前言1 課題背景2 使用CNN進行貓狗分類3 數據集處理4 神經網絡的編寫5 Tensorflow計算圖的構建6 模型的訓練和測試7 預測效果8 最后 0 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度學習貓狗分類 ** 該項目較為新穎&a…

Python測試框架pytest介紹用法

1、介紹 pytest是python的一種單元測試框架&#xff0c;同自帶的unittest測試框架類似&#xff0c;相比于unittest框架使用起來更簡潔、效率更高 pip install -U pytest 特點&#xff1a; 1.非常容易上手,入門簡單,文檔豐富&#xff0c;文檔中有很多實例可以參考 2.支持簡單的單…