封裝:隱藏代碼實現 複用 修改方便
繼承:
多態:
面試是好解析物件導向
最好立即拿周圍的事務來說
比如桌子
先分析類:桌子和椅子
他們都是傢具
所以定義一個傢具類 它是怎麼材料 這個就是屬性
它能做什麼 這個就是方法 比如能坐 能放東西在上面
然後定義一個椅子類 它應該是傢具 所以繼承自傢具類
它也有一個屬性 它還有另外的屬性 比如高度 等
我們把椅子封裝到一個類裡面 然後通過這個類 我們就可以
製作很多個物件
比如椅子1號 椅子2號 然後我們再定義一個person類
它只要調用椅子的方法 就可以使用它的方法 我們無需
知道椅子內內部是如何?的
因為所有椅子都有一個
--------------------------------------------
enum 星期{周日,周一,周二,周二......}
--------------------------------------------
internal 程式集裡面訪問public 引入命名空間就能訪問private 類內部能訪問protected 類內部和子類能訪問
--------------------------------------------
this和構造方法
public Person(string name):this(50,name)//這裡調用另外一個構造方法 並且年齡是預設50{}public Person(int age,string name){this.name = name;this.age = age;}
this在方法中使用 代表它所在的類在堆裡面的對象
--------------------------------------------
命名空間 虛擬檔案夾系統
右擊專案檔 屬性 有個程式集名稱 就是bin裡面exe的名稱
預設命名空間和項目一樣 我們修改項目名 但預設命名空間沒有變 要手動修改
輸出類型 有程式集 和控制台應用程式
命名空間和程式集名稱 本身沒有什麼相關
匯入命名空間 using system.data;
寫命名空間
namespace MySpace
{
class Person
{
}
}
在另一個命名空間裡面 如果要想訪問Person對象 那麼要引入 using MySpace
這樣 我們就可以 new Person對象 Person mai = new Person();
如果在另個命名空間裡面有同名的類 那麼我們訪問的時候 就要 命名空間.類名
在同一個命名空間裡面 可以建立多個類 比如
namespace MySpace{class Person{}Class Aminal{}}
同一個項目下面 每個cs命名空間預設是一樣的
--------------------------------------------
new 子類時候 先建立子類對象 調用子類的建構函式(此時還沒有執行子類建構函式方法體)
建立父類對象 調用父類建構函式 最後翻來執行子類的建構函式方法體代碼
顯示調用父類構造方法 base()
顯示調用當前類的另外建構函式
public Person(string name):this(50,name)//這裡調用另外一個構造方法 並且年齡是預設50{}public Person(int age,string name){this.name = name;this.age = age;}
--------------------------------------------
裡氏替換原則-子類可以替換父類的位
父類 子類
Person p = new Student()
p.Say();//此時會調用父類類的say方法
但 如果父類沒有say方法 那麼會報錯 因為父類的類型指標 只會找父類的的成員
如果我們想調用子類的 那麼就要把p轉換為student
student s = p as student;
當建立一個子類對象 聲明的是父類對象 那麼只能調用父類的方法
但當建立的子類對象 聲明的子類對象 那麼先看子類對象中是否有該方法 如果沒有則調用父類的 如果父類也沒有 則出錯
--------------------------------------------
LSP裡氏替換原則
不能將父類對象 強制轉換為子類對象
子類 0 = (子類) new 父類() 這樣是錯的
除非你當前對象 本來就是一個子類
比如
Pserson p = new Student();Student s = (Student)c;s.Say();Pserson p = new Teacher();子類可以隱式轉換為父類的Teacher t = (Teacher)p;父類可以強轉成子類is 和astypeA is typeB 僅判斷typeA as typeB 先判斷,在轉換
--------------------------------------------
簡單原廠模式
static Person GetPerson(string typeStr){switch(typeStr){case "teacher":return new Teacher();case "Student":return new Student();default:return new Person();}}static void TestSimpleFactory(){Pserson p = GetPerson("Teacher");p.SayHi();}
-----------------------------------------------
多態 (方法重寫)
三個條件
1.有繼承關係
class Student:Person
2.子類方法重寫父類方法
Person 中寫一個虛方法 可以被子類重寫
public virtual void SayHi(){consoloe.....}Student 中 重寫該方法public override void SayHi(){dd...}
3.父類引用指向子類對象
Person p = new Student();
p.Say();//這時候 它真的會調用子類的方法
--------------------------------------------
AS IS
Person p = new Student();if(p is Student)//判斷p是否是Student的子類或者就是Student{Student s = (Student)p;}如果用as Student s = p as Student;
--------------------------------------------
抽象類別
抽象類別裡面可以有非抽象方法
public abstract class AbstractClass{pulic void SayHi(){}public abstract void AbsMethod();//抽象方法}
abstract要寫到class關鍵字外面
--------------------------------------------
abstract class Class1
{
public void Say()
{
Console.WriteLine("抽象類別裡面可以沒有抽象方法");
}
}
//但抽象類別不能new
--------------------------------------------
抽象類別不能執行個體化(不能new)
抽象類別可以有抽象方法 也可以沒有
一般類不能有抽象方法
誰繼承了抽象類別 要麼也寫成抽象類別 要麼實現抽象類別的所有抽象方法
--------------------------------------------
介面也是參考型別 類似類 和抽象類別相似之處 三點
1、不能執行個體化
2、包括未實現的方法聲明
3、子類必須實現未實現的方法
--------------------------------------------
介面的一些常見錯誤
private interface Interface1
{
}
錯誤 1 命名空間中定義的元素無法顯式聲明為 private、protected 或 protected internal
--------------------------------------------
interface Interface1
{
void Say();
}
錯誤 2 介面中的方法 不能有public修飾 private 等
--------------------------------------------
interface Interface1
{
void Say()
{
Console.WriteLine("介面中可以有方法實現???");
}
}
錯誤 3 “ConsoleApplication1.Interface1.Say()”: 介面成員不能有定義
--------------------------------------------
父類方法 如果沒有標記位virtual
子類override這個方法 那麼可能會錯
namespace ConsoleApplication1{class Program{static void Main(string[] args){Person p = new Student();p.SayHi();Console.ReadKey();}}class Person{public void SayHi(){Console.WriteLine("person.sayhi");}}class Student:Person{public override void SayHi(){Console.WriteLine("student.sayHi");}}}
錯誤 1“ConsoleApplication1.Student.SayHi()”: 繼承成員“ConsoleApplication1.Person.SayHi()”未標記為 virtual、abstract 或
override,無法進行重寫
--------------------------------------------
虛方法 和抽象方法 區別
1、虛方法必須有實現 抽象方法 必須沒有實現
2、抽象方法必須在抽象類別中聲明,虛方法可以出現在抽象類別中
3、抽象方法必須在子類中重寫,虛方法可以被重寫
實現多態的主要手段
1 虛方法virtual
2 抽象方法abstract
3 介面
關於虛方法需要注意的幾點
1 父類如果有方法需要讓子類重寫 則可以將該方法標記為virtual
2 虛方法在父類中必須實現,那片是空實現
3 虛方法子類可以重寫override 也可以不重寫
不重寫 就沒有多態 調用的時候 父類的指標類型則調用父類的 子類的指標類型則調用子類的
--------------------------------------------
new關鍵字 和overr visual
namespace ConsoleApplication1{class Program{static void Main(string[] args){Person p = new Student();p.SayHi();//由於子類重寫了 所以調用子類對象 體現多態Person p1 = new Teacher();p1.SayHi();//直接調用父類的方法Teacher t = new Teacher();t.SayHi();//這裡直接調用子類的 但如果子類方法沒有new 則可能出現警告Console.ReadKey();}}class Person{public virtual void SayHi(){Console.WriteLine("person.sayhi");}}class Student:Person{public override void SayHi(){Console.WriteLine("student.sayHi");}}class Teacher:Person{public new void SayHi(){Console.WriteLine("teacher.sayhi");}//上面那裡如果沒有new 則會警告 new的作用是 隱藏父類的方法 因為父類也有同樣的方法 而且是虛方法virtual//加個new的意思是 子類的這個方法 是子類新的方法 不是重寫父類的方法}}