c# class 继承

2019-09-30  本文已影响0人  柒轩轩轩轩

继承

public class Asset
{
  public string Name;
}

public class Stock: Asset 
{
public long SharesOwned;
}

...
Stock msft = new Stock { Name = "MSFT", SharesOwned = 1000}
Console.WriteLine(msft.Name); //MSFT
Console.WriteLine(msft.SharesOwned)  // 1000

多态

public static void Display (Asset asset) 
{
  System.Console.WriteLine(asset.Name)
}

Stock msft = new Stock { Name = "MSFT", SharesOwned = 1000};
Diaplay(msft);

引用转换

向上转换

Stock msft = new Stock();
Asset a = msft;
Console.WriteLine(a == msft) //Ture
Console.WriteLine(a.Name); //OK
Console.WriteLine(a.SharedOwned); //Error

向下转换

Stock msft = new Stock();
Asset a = msft; //Upcast
Stock s = (Stock)a; //DownCast
Console.WriteLine(s.SharesOwned); //<No Error>
Console.WriteLine(s == a); // True
Console.WriteLine(s == msft); //True

as操作符

Asset a = new Asset();
Stock s = a as Stock; //s is null; no exception thrown

is操作符

if(a is Stock)
Console.WriteLine( ((Stock)a).SharedOwned);
if (a is Stock s)
Console.WriteLine(s.SharedOwned);
if (a is Stock s && s.SharedOwned > 100000)
  Console.WriteLine('Wealthy");
else
  s = new Stock(); //s is in scope
Console.WriteLine(s.SharedOwned;

Virtual 函数成员

public class Asset
{
public string Name;
public virtual decimal Liability => 0;
}

Override 重写

public class Stock: Asset
{
  public long SharesOwned;
}
public class House : Asset 
{
  public decimal Mortage;
  public override decimal Liability => Mortage;
}

...
House mansion = new House { Name ="McMansion", Mortgage = 2500000};
Asset a = massion;
Console.WriteLine(mansion.Liability); //2500000
Console.WriteLine(a.Liability); //2500000

抽象类和抽象成员

public abstract  class Asset
{
  //Note empty implementation
public abstract decimal NetValue {get;}
}
public class Stock: Asset 
{
  public long SharesOwned;
  public decimal CurrentPrice;
//Override like a virtual method;
  public override decimal NetValue => CurrentPrice * SharesOwned
}

隐藏被继承的成员

public class A {public int Counter = 1;}
public class B: A { public int Counter = 2;}

class B中的Counter字段就隐藏了A里面的Couter字段(通常是偶然发生的)例如子类添加某个字段之后
编译器会发出警告

隐藏被继承的成员

按照如下规则进行解析:

class Program 
{
  static void Main() 
{
  A a = new  A();
  System.Console.WriteLine(a.Counter);//1  

  B b = new B();
  System.Console.WriteLine(b.Counter); //2

  A x = new B ();
  System.Console.WriteLine(x.Counter); //1

}
}
public class A { public int Counter = 1; }
public class B: A {public new int Counter = 2;}

New vs Override

public class BaseClass
{
  public virtual void Foo() { Console.WriteLine('Overrider.Foo");}
}

public class Overrider: BaseClass 
{
  public override void Foo() {Console.WriteLine("Overrider.Foo")}
}

public class Hider: BaseClass
{
  public new void Foo() {Console.WriteLine("Hider.Foo");}
}

Overrider over = new Overrider();
BaseClass b1 = over;
over.Foo(); //Overrider.Foo
b1.Foo(); //Overrider.Foo

Hider h = new Hider();
BaseClass b2 = h;
h.Foo(); //Hider.Foo
b2.Foo(); //BaseClass.Foo

Sealed

public sealed override decimal Liability {get {return Mortgage;}}

Base 关键字

base和this略像,base主要用于:

public class House: Asset 
{
  ...
  public override decimal  Liability => base.Liabiliry + Mortgage;
}

构造函数和继承

public class Baseclass 
{
  public int x;
  public Baseclass() {}
  public Baseclass(int x) {this.x = x;}
}
public class Subclass: Baseclass {
  public Subclass(int x): base(x) { }
}

class Program
{
  static void Main(string[] args)
  {
    Subclass s = new Subclass(123);
  }
}

隐式调用无参的父类构造函数

public class Baseclass
{
  public int x;
  public Baseclass() {x = 1;}
}
public class Subclass: Baseclass
{
  public Subclass() { Console.WriteLine(x); } // 1
}

构造函数和字段初始化顺序

对象被实例化时, 初始化动作按照如下顺序进行:

  1. 从子类到父类:
  1. 从父类到子类
  public class B
  {
    int x = 1;  //Executes 3rd
    public B (int x) 
    {
    ...        // Executes 4th
    }
  }

  public class D:B
  {
     int y = 1; //Execites 1st
     public D(int x) :base (x +1) //Executes 2nd
  {
    ... //Executes 5th
  }
  }

重载和解析

static void Foo (Assst a) { }
static void Foo (House s) { }
House h = new House(...);
Foo(h); //Calls Foo(house)
- 调用哪个重载方法是在编译时就确定下来了

Asset a = new House(...);
Foo(a); //calls Foo(Asset)

上一篇 下一篇

猜你喜欢

热点阅读