香蕉视频app

Keep on going never give up.

Let's Go

C# 學習筆記(40)面向對象三大特性之繼承

C#Lonely2019-05-16 18:56:0747次0條

在c#中,一個類可以繼承另外一個已有的類(密封類除外),被繼承的類稱為基類(或父類),繼承的類稱為派生類(或子類),子類將獲得基類除構造函數和析構函數以外的所有成員。此外,靜態類是密封的,也不能被繼承。

例如,學生、老師、程序員等都是屬于人類,但他們是不同職業的人類,除了具有人類的共同性外,他們還具有各自的特點,如不同的身份、不同的工作方式等。我們可以把人類定義為學生、老師、程序員的父類,這樣子類不但繼承了基類除構造函數和析構函數以外的所有成員,還可以添加自己特有的成員。

通過繼承,程序可實現對父類代碼的復用。因為子類可繼承父類的所有成員,父類中定義的代碼便不需要在子類中進行重復定義了。

代碼示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Person
    {
        private string _name;
        private char _sex;
        private int _age;
        
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        
        public char Sex
        {
            get
            {
                return _sex;
            }
            set
            {
                _sex = value;
            }
        }
        
        public int Age
        {
            get
            {
                return _age;
            }
            set
            {
                _age = value;
            }
        }
        
        public Person(string name,char sex,int age)
        {
            this.Name = name;
            this.Sex = sex;
            this.Age = age;
            Console.WriteLine("我是Person類的構造函數,我被調用了");
        }
        
        public void SayHello()
        {
            Console.WriteLine("大家好!我是人類");
        }
        
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Student: Person //Student類繼承Person類
    {
        private int stuId; //學號
        private double score; //分數

        public Student(string name,char sex ,int age, int stuId, double score) : base(name, sex, age)
        {
            this.StuId = stuId;
            this.Score = score;
            Console.WriteLine("我是Student類的構造函數,我被調用了");
        }

        public int StuId
        {
            get
            {
                return stuId;
            }

            set
            {
                stuId = value;
            }
        }

        public double Score
        {
            get
            {
                return score;
            }

            set
            {
                score = value;
            }
        }

        public void study()
        {
            Console.WriteLine("我是一名學生,我要學習各門功課。");
        }

        //使用關鍵字new隱藏父類成員。new創建對象后,隱藏從父類那里繼承過來的同名成員。隱藏的后果就是子類調用不到父類的成員,所以盡量不要把子類成員名寫得跟父類一樣。
        public new void SayHello()
        {
            Console.WriteLine("大家好!我是學生類");
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Teacher: Person //Teacher類繼承Person類
    {
        private int jobId; //教工號
        private double salary; //薪水
       
        public Teacher(string name, char sex, int age, int jobId, double salary) : base(name, sex, age)
        {
            this.JobId = jobId;
            this.Salary = salary;
            Console.WriteLine("我是Teacher類的構造函數,我被調用了");
        }

        public int JobId
        {
            get
            {
                return jobId;
            }
            set
            {
                jobId = value;
            }
        }

        public double Salary
        {
            get
            {
                return salary;
            }

            set
            {
                salary = value;
            }
        }

        public void work()
        {
            Console.WriteLine("我是老師,我的工作內容是教書。");
        }

        //使用關鍵字new隱藏父類成員。new創建對象后,隱藏從父類那里繼承過來的同名成員。隱藏的后果就是子類調用不到父類的成員,所以盡量不要把子類成員名寫得跟父類一樣。
        public new void SayHello()
        {
            Console.WriteLine("大家好!我是教師類");
        }


    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student("盛婷婷",'女',18,1001,98.5);
            Console.WriteLine("姓名:{0},性別:{1},年齡:{2},學號:{3},成績:{4}",stu.Name,stu.Sex,stu.Age,stu.StuId,stu.Score);
            stu.study();
            stu.SayHello();
            
            //如果此時仍然想訪問基類的成員,則可以使用強制類型轉換,把子類強制轉換成基類,從而訪問隱藏的基類成員。
            //((Person)stu).SayHello(); //輸出了 大家好!我是人類
            
            Teacher tea = new Teacher("陳大文", '男', 40, 32, 6500);
            Console.WriteLine("姓名:{0},性別:{1},年齡:{2},教工號:{3},工資:{4}", tea.Name, tea.Sex, tea.Age, tea.JobId, tea.Salary);
            tea.work();
            tea.SayHello();
            
            Console.ReadKey();
        }
    }
}

運行結果:

image.png

類圖

image.png

查看類圖香蕉视频app解決方法資源管理器-->項目-->右鍵-->查看-->查看類圖

總結:

繼承:父類(基類)、子類(派生類)

我們可能會在一些類中,寫一些重復的成員,我們可以將這些重復的成員,單獨的封裝到一個類中,作為這些類的父類。

繼承的特性:

(1)、繼承的單根性香蕉视频app:一個子類只能繼承一個父類,不能同時繼承多個父類。C#中,派生類只能從一個類中繼承。C#不支持多重繼承,通俗的說就是兒子只能有一個親生父親,不能同時擁有多個親生父親。C#可以繼承多個接口。

(2)、繼承的傳遞性香蕉视频app:派生類從基類那里繼承特性。派生類也可以作為其它類的基類。從一個基類派生出來的多層類形成了類的層次結構。通俗的說就是爺爺、爸爸、兒子的關系,兒子能訪問爸爸、爺爺的公有成員,爸爸能訪問爺爺的公有成員但不能訪問兒子的公有成員。

香蕉视频app class A

{

}

class B : A

{

}

//A是基類,B是派生類,一個類最多只允許從一個類中派生。

香蕉视频app class C : B

{

}

//C還能繼承B,充當B的派生類。


問:子類繼承了父類,那么子類從父類那里繼承過來了什么?

答:子類繼承了父類的屬性和方法,但子類并沒有繼承父類的私有字段。

問:子類有沒有繼承父類的構造函數和析構函數?

答:子類并沒有繼承父類的構造函數和析構函數,但是子類會默認的調用父類無參數的構造函數(用來創建父類對象,讓子類可以使用父類中的成員。)所以如果在父類寫了一個有參數的構造函數之后,那個默認的無參數的構造函數就被干掉了,因此子類就調用不到了,所以子類會報錯。

解決方法:

方法一:在父類重新寫一個無參數的構造函數。

香蕉视频app 方法二:一般都采用這種方法,在子類用顯式的調用父類的構造函數,使用關鍵字 :base() 去調用父類的構造函數。

new關鍵字用途:

香蕉视频app (1)、創建對象。

(2)、使用關鍵字new隱藏父類成員。new創建對象后,隱藏從父類那里繼承過來的同名成員。隱藏的后果就是子類調用不到父類的成員,所以盡量不要把子類成員名寫得跟父類一樣。如果此時仍然想訪問基類的成員,則可以使用強制類型轉換,把子類強制轉換成基類,從而訪問隱藏的基類成員。例如:((Person)stu).SayHello();

子類的初始化順序:

使用了繼承之后,當我們初始化一個子類時,除了會調用子類的構造函數外,同時也會調用基類的構造函數。子類的初始化順序如下:

(1)、初始化類的實例字段。

香蕉视频app (2)、調用基類的構造函數,如果沒有指明基類,則調用System.Object的構造函數。

(3)、調用子類的構造函數。

所有類的父類:System.Object

在C#中,所有的類都直接或間接繼承System.Object類,如果定義的類沒有指定任何基類,編譯器就會自動把System.Object類當作它的基類。和其他類一樣,System.Object類也定義了一組共有的成員,其定義如下:

public class Object
{
    //方法
    //構造函數
    public Object();
    
    //虛成員
    public virtual bool Equals(object obj);
    protected virtual void Finalze();
    public virtual int GetHashCode();
    public virtual string ToString();
    
    //實例成員
    public Type GetType();
    protected Object MemberwiseClone();
    
    //靜態成員
    public static bool Equals(Object objA, Object objB);
    public static bool ReferenceEquals(Object objA, Object objB);
            
}


暗錨,解決錨點偏移

文章評論

    嘿,來試試登錄吧!