Golang面向對象編程(二)

文章目錄

  • 封裝
    • 基本介紹
    • 封裝的實現
    • 工廠函數
  • 繼承
    • 基本介紹
    • 繼承的實現
    • 字段和方法訪問細節
    • 多繼承

封裝

基本介紹

基本介紹

  • 封裝(Encapsulation)是面向對象編程(OOP)中的一種重要概念,封裝通過將數據和相關的方法組合在一起,形成一個稱為類的抽象數據類型,只暴露必要的接口供外部使用。
  • 封裝可以隱藏數據的實際實現細節,外部只能通過公共(public)接口來訪問和修改數據,使得代碼更加模塊化和結構化,同時可以防止不恰當的訪問和操作,提高數據的安全性。
  • 封裝將相關的數據和方法組織在一起,形成了一個獨立的單元,外部使用者只需關心公共接口,無需了解內部實現細節,簡化了使用方式,提高了代碼的可讀性和可維護性。
  • 封裝使得內部實現可以獨立于外部接口進行修改,如果內部實現發生了變化,只需要確保公共接口的兼容性,而不會影響使用該類的其他代碼,提供了更好的靈活性和可擴展性。

封裝的實現

封裝的實現

  • Go中的封裝是通過命名約定和訪問控制來實現的,而不像一些其他面向對象語言那樣使用訪問修飾符(如public、private、protected),因此開發者需要自覺遵守約定來保持封裝的效果。
  • Go中通過結構體將相關的字段和方法組合在一起,并通過首字母大小寫來控制其可訪問性。結構體中的字段和方法使用大寫字母開頭表示公共的(可導出的),可以被其他包訪問,而使用小寫字母開頭表示私有的(不可導出的),只能在當前包內使用。
  • Go中的封裝更加寬泛,其封裝的基本單元不是結構體而是包(package),包內的所有標識符(變量、函數、結構體、方法等)都通過首字母大小寫來控制其可訪問性

封裝案例如下:

package modelimport "fmt"type Student struct {name   stringage    intgender string
}// 訪問name字段
func (stu Student) GetName() string {return stu.name
}
func (stu *Student) SetName(name string) {stu.name = name
}// 訪問age字段
func (stu Student) GetAge() int {return stu.age
}
func (stu *Student) SetAge(age int) {stu.age = age
}// 訪問gender字段
func (stu Student) GetGender() string {return stu.gender
}
func (stu *Student) SetGender(gender string) {stu.gender = gender
}// Student的其他方法
func (stu Student) Print() {fmt.Printf("student info: <name: %s, age: %d, gender: %s>\n",stu.name, stu.age, stu.gender)
}

使用上述包內結構體的案例如下:

package mainimport ("go_code/OOP2/Encapsulate/model"
)func main() {// var stu = model.Student{"Alice", 12, "女"} // 隱式賦值var stu model.Studentstu.SetName("Alice")stu.SetAge(12)stu.SetGender("女")stu.Print() // student info: <name: Alice, age: 12, gender: 女>
}

注意: Go中無法對結構體中不可導出的字段進行隱式賦值,可以通過給結構體綁定對應的setter和getter方法對不可導出的字段進行訪問和賦值。

工廠函數

工廠函數

如果結構體類型的首字母小寫(不可導出),那么其他包將無法直接使用該結構體類型來創建實例,這時可以在包內提供對應可導出的工廠函數來創建實例并返回。如下:

package modelimport "fmt"type student struct {name   stringage    intgender string
}// 工廠函數
func NewStudent(name string, age int, gender string) *student {return &student{name:   name,age:    age,gender: gender,}
}func (stu student) Print() {fmt.Printf("student info: <name: %s, age: %d, gender: %s>\n",stu.name, stu.age, stu.gender)
}

其他包通過調用包中可導出的工廠函數,即可創建對應不可導出的結構體實例。如下:

package mainimport ("go_code/OOP2/Encapsulate/model"
)func main() {var stu = model.NewStudent("Alice", 12, "女")stu.Print() // student info: <name: Alice, age: 12, gender: 女>
}

繼承

基本介紹

基本介紹

  • 繼承是面向對象編程中的一個重要概念,其允許一個類(子類/派生類)繼承另一個類(父類/基類)的屬性和方法,子類繼承父類后可以直接訪問和使用父類中字段和方法,同時可以添加自己的字段和方法。
  • 繼承的主要優勢在于代碼復用,繼承可以在不重復編寫相似代碼的情況下擴展現有的類,使代碼更具可維護性和可擴展性。

繼承示意圖如下:

在這里插入圖片描述

繼承的實現

繼承的實現

  • Go中的繼承是通過嵌套匿名結構體的方式來實現的,如果一個結構體中嵌套了另一個匿名結構體,那么這個結構體可以直接訪問匿名結構體中的字段和方法,從而實現了繼承的效果。

繼承案例如下:

package mainimport ("fmt"
)// 基類
type Person struct {Name stringAge  int
}
func (per Person) PrintInfo() {fmt.Printf("name = %s, age = %d\n", per.Name, per.Age)
}// 派生類
type Student struct {Person    // 嵌套匿名結構體StudentId int
}
func (stu Student) Study() {fmt.Printf("student %d is studying...\n", stu.StudentId)
}// 派生類
type Teacher struct {*Person   // 嵌套匿名結構體指針TeacherId int
}
func (tch Teacher) Teach() {fmt.Printf("teacher %d is teaching...\n", tch.TeacherId)
}func main() {var stu = Student{Person{"Alice", 12}, 100}stu.PrintInfo() // name = Alice, age = 12stu.Study()     // student 100 is studying...var tch = Teacher{&Person{"Bob", 22}, 200}tch.PrintInfo() // name = Bob, age = 22tch.Teach()     // teacher 200 is teaching...
}

說明一下:

  • 在嵌套匿名結構體時,可以通過Type的方式嵌套匿名結構體,也可以通過*Type的方式嵌套匿名結構體指針。
  • 在創建結構體變量時,如果要通過字段名的方式初始化結構體字段,那么匿名結構體的字段名由匿名結構體的類型名充當。
  • 在結構體中嵌套匿名結構體后,可以通過結構體實例訪問匿名結構體的字段和方法,但在訪問時仍然遵循Go的命名約定和訪問控制。如果被嵌套的匿名結構體的定義在其他包,那么通過結構體實例只能訪問匿名結構體可導出的字段和方法。
  • 結構體中嵌入的匿名字段也可以是基本數據類型,在訪問結構體中的匿名基本數據類型字段時,以對應基本數據類型的類型名作為其字段名。比如結構體中嵌入了一個匿名int字段,則通過結構體變量名.int的方式對其進行訪問。

組合

在結構體中嵌套有名結構體屬于組合關系,在訪問組合的結構體字段和方法時,必須帶上結構體的字段名。如下:

package mainimport ("fmt"
)// 車輪
type Wheel struct {Color stringprice int
}// 自行車
type Bicycle struct {FrontWheel Wheel // 組合RearWheel  Wheel // 組合// ...
}
func (bc Bicycle) Print() {fmt.Printf("前輪<color:%s, price:%d元> 后輪<color:%s, price:%d元>\n",bc.FrontWheel.Color, bc.FrontWheel.price, bc.RearWheel.Color, bc.RearWheel.price)
}func main() {var bc = Bicycle{FrontWheel: Wheel{"black", 100},RearWheel:  Wheel{"blue", 200},}bc.Print() // 前輪<color:black, price:100元> 后輪<color:blue, price:200元>
}

字段和方法訪問細節

字段和方法訪問細節

結構體字段和方法的訪問流程:

  1. 先查看當前結構體類型中是否有對應的字段或方法,如果有則訪問。
  2. 再查看結構體中嵌入的匿名結構體中是否有對應的字段或方法,如果有則訪問。
  3. 繼續查找更深層次嵌入的匿名結構體中是否有對應的字段或方法,如果有則訪問,否則產生報錯。

案例如下:

package mainimport ("fmt"
)// 基類
type Person struct {Name stringAge  int
}
func (per Person) PrintInfo() {fmt.Printf("name = %s, age = %d\n", per.Name, per.Age)
}// 派生類
type Student struct {PersonStudentId int
}func (stu Student) Study() {fmt.Printf("student %d is studying...\n", stu.StudentId)
}
func (stu Student) PrintInfo() {fmt.Printf("name = %s, age = %d, id = %d\n", stu.Name, stu.Age, stu.StudentId)
}func main() {var stu = Student{Person{"Alice", 12}, 100}fmt.Printf("name = %s\n", stu.Name) // name = Alicestu.PrintInfo()                     // name = Alice, age = 12, id = 100
}

代碼說明:

  • 在訪問字段時,由于Student結構體中沒有Name字段,因此Student變量.Name訪問的是嵌套的匿名結構體Person中的Name字段。
  • 在訪問方法時,由于Student結構體有PrintInfo方法,因此Student變量.PrintInfo()訪問的是Student結構體的PrintInfo方法,而不是Person結構體的PrintInfo方法。

多繼承

多繼承

多繼承指的是一個結構體中嵌套了多個匿名結構體,如果嵌套的多個匿名結構體中有相同的字段名或方法名,那么在訪問時需要通過匿名結構體的類型名進行指明訪問。如下:

package mainimport ("fmt"
)type Cat struct {Name stringAge  int
}type Dog struct {Name stringAge  int
}// 多繼承
type Pet struct {CatDog
}func main() {var pet = Pet{Cat: Cat{Name: "小貓",Age:  2,},Dog: Dog{Name: "小狗",Age:  3,},}fmt.Printf("cat name = %s\n", pet.Cat.Name) // cat name = 小貓fmt.Printf("dog name = %s\n", pet.Dog.Name) // dog name = 小狗
}

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

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

相關文章

java JOptionPane 介紹

JOptionPane是Java Swing庫中的一個類,用于創建對話框(Dialogs),以便與用戶進行交互。它提供了一種簡單的方式來顯示消息、警告、錯誤、輸入框等。 主要方法: showMessageDialog(Component parentComponent, Object message):顯示一個包含消息的對話框。showInputDialog…

2024OD機試卷-手機App防沉迷系統 (java\python\c++)

題目:手機App防沉迷系統 題目描述 智能手機方便了我們生活的同時,也侵占了我們不少的時間。 “手機App防沉迷系統”能夠讓我們每天合理地規劃手機App使用時間,在正確的時間做正確的事。 它的大概原理是這樣的: 在一天24小時內,可以注冊每個App的允許使用時段一個時間段只…

Java轉Kotlin調用JNI方法異常

一、背景 Java調用JNI方法時沒有任何問題&#xff0c;但是使用Java轉Kotlin以后出現了崩潰異常&#xff1a;A java_vm_ext.cc:597] JNI DETECTED ERROR IN APPLICATION: jclass has wrong type: 校驗參數后沒有任何變化&#xff0c;經過分析驗證找到解決方案 二、原因…

若依生成樹表和下拉框選擇樹表結構(在其他頁面使用該下拉框輸入)

1.數據庫表設計 生成樹結構的主要列是id列和parent_id列&#xff0c;后者指向他的父級 2.來到前端代碼生成器頁面 導入你剛剛寫出該格式的數據庫表 3.點擊編輯&#xff0c;來到字段 祖籍列表是為了好找到直接父類&#xff0c;不屬于代碼生成器方法&#xff0c;需要后臺編…

【XSRP軟件無線電】基于軟件無線電平臺的QPSK頻帶通信系統設計

目錄&#xff1a; 目錄&#xff1a; 一、緒論 1.1 設計背景 1.2 設計目的 二、系統總體方案 2.1 專題調研題目 2.2 調研背景 2.3 設計任務解讀 2.4 設計原理 2.4.1 原理框圖 2.4.2 功能驗證 三、軟件設計 3.1 程序解讀 3.2 程序設計 3.3 仿真結果&#xff1a; 四、程序代碼分析…

網絡基礎-SSH協議(思科、華為、華三)

SSH&#xff08;Secure Shell&#xff09;是一種用于安全遠程訪問和安全文件傳輸的協議。它提供了加密的通信通道&#xff0c;使得用戶可以在不安全的網絡上安全地遠程登錄到遠程主機&#xff0c;并在遠程主機上執行命令、訪問文件以及傳輸文件&#xff0c;本篇主要講解命令執行…

SpringAI集成本地AI大模型ollama(調用篇)非常簡單!!

一&#xff0c;前提準備本地ai模型 1&#xff0c;首先需要去ollama官網下載開源ai到本地 網址&#xff1a;Ollama 直接下載到本地&#xff0c;然后啟動ollama 啟動完成后&#xff0c;我們可以在cmd中執行ollama可以看到相關命令行 2&#xff0c; 下載ai moudle 然后我們需要…

基于C#開發web網頁模板流程-登錄界面

前言&#xff0c;首先介紹一下本項目將要實現的功能 &#xff08;一&#xff09;登錄界面 實現一個不算特別美觀的登錄窗口&#xff0c;當然這一步跟開發者本身的設計美學相關&#xff0c;像蒟蒻博主就沒啥藝術細胞&#xff0c;勉強能用能看就行…… &#xff08;二&#xff09…

【vector】迭代器

Vector的基本數據結構 可以看到end指向的是數組的最后一個元素&#xff1b; 那么在使用函數遍歷的時候就要注意這種清理&#xff1b; 比如計算一個數組前5個數字的最小值&#xff1b; vector<int> prices{2,1,4,2,0,52,12};auto iter_min min_element(prices.begin(),pr…

NSSCTF | [LitCTF 2023]我Flag呢?

這道題沒啥好說的&#xff0c;題目標簽為源碼泄露&#xff0c;我們直接CtrlU查看網頁源碼就能在最后找到flag 本題完

深入學習指針2

前言 hello,我又來了&#xff0c;今天有我繼續帶領大家深入的學習指針&#xff0c;通過上次的學習&#xff0c;我們已經了解到了指針的基本概念&#xff0c;指針如何使用&#xff0c;指針使用的益處&#xff0c;以及一些相關的概念&#xff0c;那今天我們就繼續深入的學習&am…

Vue3專欄項目 -- 二、自定義From組件(下)

需求分析&#xff1a; 現在我們還需要一個整體的表單在單擊某個按鈕的時候可以循環的驗證每個input的值&#xff0c;最后我們還需要有一個事件可以得到最后驗證的結果&#xff0c;從而進行下一步的操作 如下&#xff0c;我們應該有一個form表單包裹著全部的input表單&#xf…

Java面試八股之Java中的IO流分為幾種

Java中的IO流分為幾種 按數據單位分類&#xff1a; 字節流&#xff08;Byte Stream&#xff09;&#xff1a;以字節&#xff08;8位二進制數&#xff09;為基本單位進行數據讀寫。字節流適合處理所有類型的數據&#xff0c;包括文本、圖像、音頻、視頻等二進制文件。抽象基類…

打破地域界限,HubSpot海外獲客系統引領企業走向國際化

在全球化的浪潮中&#xff0c;企業如何精準把握海外市場、高效獲取并轉化目標客戶&#xff0c;已成為決定其市場地位與未來發展的關鍵因素。HubSpot海外獲客系統以其獨特的視角、強大的功能和卓越的性能&#xff0c;正在引領全球營銷進入一個新的時代。今天運營壇將深入剖析Hub…

阿里巴巴找黃金寶箱(II) - 貪心思維

系列文章目錄 文章目錄 系列文章目錄前言一、題目描述二、輸出描述三、輸入描述四、java代碼五、測試用例 前言 本人最近再練習算法&#xff0c;所以會發布自己的解題思路&#xff0c;希望大家多指教 一、題目描述 一貧如洗的樵夫阿里巴巴在去砍柴的路上&#xff0c;無意中發…

KUKA機器人專業名詞解釋

1、CCU Cabinet Control Unit &#xff08;控制柜控制單元&#xff09; 2、CIB Cabinet Interface Board &#xff08;控制柜接口板&#xff09; 3、HMI Human Machine Interface &#xff08;人機界面&#xff09;&#xff1b;KUKA.HMI 是 KUKA 操作界面。 4、KCB …

工作組PTH

文章目錄 簡述RID 500本地管理員密碼噴灑何為RIP 500 安全標識符SID與RIDPTH為何必須是RID 500CrackMapExec進行密碼噴灑 簡述 在工作組PTH中為什么只有administrator賬號可以,下面進行講解與利用。RID 500本地管理員密碼噴灑 何為RIP 500 安全標識符 安全標識符 安全標識符…

觸摸OpenNJet,云原生世界觸手可及

&#x1f308;個人主頁: Aileen_0v0 &#x1f525;熱門專欄: 華為鴻蒙系統學習|計算機網絡|數據結構與算法 ?&#x1f4ab;個人格言:“沒有羅馬,那就自己創造羅馬~” 文章目錄 導言OpenNJet云原生引擎介紹云原生平臺的介紹優化與創新 為什么選擇OpenNJet云原生引擎如何在windo…

Pytorch基礎:torch.cuda.set_device函數

相關閱讀 Pytorch基礎https://blog.csdn.net/weixin_45791458/category_12457644.html?spm1001.2014.3001.5482 torch.cuda.set_device函數用于設置當前使用的cuda設備&#xff0c;在當擁有多個可用的GPU且能被pytorch識別的cuda設備情況下&#xff08;環境變量CUDA_VISIBLE_…

【AI大模型】自動生成紅隊攻擊提示--GPTFUZZER

本篇參考論文為&#xff1a; Yu J, Lin X, Xing X. Gptfuzzer: Red teaming large language models with auto-generated jailbreak prompts[J]. arXiv preprint arXiv:2309.10253, 2023. https://arxiv.org/pdf/2309.10253 一 背景 雖然LLM在今天的各個領域得到了廣泛的運用…