C#细节之Interface和abstract class
Interface和abstract class
OOP必谈面向“接口”编程,此接口并非仅指“Interface”,它包括“接口”和“抽象类”。
OOP中的原则很多,什么SRP,OCP,DIP,ISP,LSP。
而“接口”和“抽象类”又与DIP(依赖倒置原则)密切相关。DIP强调的是依赖抽象不依赖实际,这样可以降低系统的耦合性。举个简单的例子:
Man man = new Man();
man.Talk();
这样耦合性很高,如果改为Women两行代码都需要修改,所以演化为(Human为抽象类,依赖抽象):
Human human= new Man();
human.Talk();
如果该为Women的话就修改new Man()为new Women()即可。当然这样还是有耦合性,解决方案可以参考我设计模式文章中关于工厂的介绍,这里先写个代码供大家思考:
Human human = humanFactory.CreateHuman("xxxx");//简单工厂
human.Talk();
然而接口和抽象类的区别是什么那?
1)接口没有任何实现,抽象类可以包含实现。
2)接口支持多继承,抽象类不支持多继承。
3)继承接口的类实现接口成员时不需要其他关键字,继承抽象类的类实现抽象类成员时需要用到override或者new。
4)接口继承分为显示继承和隐式继承。隐式继承需要访问修饰符,显示不需要访问修饰符,直接用[接口名].[函数名]。
另:
override只能重写标记为virtual,abstract,override的成员。
显示实现的接口函数需要用接口对象调用,不能用实现接口的类的对象调用;隐式实现的接口均可调用。
new标记的成员当用父类对象调用时调用的是父类的方法,override标记的成员当用父类对象调用时调用的是子类的方法。
一下是代码:
OOP必谈面向“接口”编程,此接口并非仅指“Interface”,它包括“接口”和“抽象类”。
OOP中的原则很多,什么SRP,OCP,DIP,ISP,LSP。
而“接口”和“抽象类”又与DIP(依赖倒置原则)密切相关。DIP强调的是依赖抽象不依赖实际,这样可以降低系统的耦合性。举个简单的例子:
Man man = new Man();
man.Talk();
这样耦合性很高,如果改为Women两行代码都需要修改,所以演化为(Human为抽象类,依赖抽象):
Human human= new Man();
human.Talk();
如果该为Women的话就修改new Man()为new Women()即可。当然这样还是有耦合性,解决方案可以参考我设计模式文章中关于工厂的介绍,这里先写个代码供大家思考:
Human human = humanFactory.CreateHuman("xxxx");//简单工厂
human.Talk();
然而接口和抽象类的区别是什么那?
1)接口没有任何实现,抽象类可以包含实现。
2)接口支持多继承,抽象类不支持多继承。
3)继承接口的类实现接口成员时不需要其他关键字,继承抽象类的类实现抽象类成员时需要用到override或者new。
4)接口继承分为显示继承和隐式继承。隐式继承需要访问修饰符,显示不需要访问修饰符,直接用[接口名].[函数名]。
另:
override只能重写标记为virtual,abstract,override的成员。
显示实现的接口函数需要用接口对象调用,不能用实现接口的类的对象调用;隐式实现的接口均可调用。
new标记的成员当用父类对象调用时调用的是父类的方法,override标记的成员当用父类对象调用时调用的是子类的方法。
一下是代码:
using System;
class Stater
{
static void Main()
{
//抽象类
AbstractClass abstractClass = new TestTwo();
abstractClass.Init();
abstractClass.Show();
abstractClass.ShowTwo();//new覆盖,调用父类方法
abstractClass.ShowThree();//override重写,调用子类方法
TestTwo ttObj = new TestTwo();
ttObj.Init();
ttObj.Show();
ttObj.ShowTwo();//new覆盖,调用子类方法
ttObj.ShowThree();//override重写调用子类方法
//接口
IInterface iinterface = new Test();
iinterface.Init();
iinterface.Show();
Test test = new Test();
//test.Init();//Error:显示声明只能接口调用
test.Show();
}
}
abstract class AbstractClass
{
public void Init()
{
Console.WriteLine("AbstractClass Init.");
}
public abstract void Show();
public virtual void ShowTwo()
{
Console.WriteLine("AbstractClass ShowTwo.");
}
public virtual void ShowThree()
{
Console.WriteLine("AbstractClass ShowThree.");
}
}
interface IInterface
{
string Property { get;}
void Init();
void Show();
}
class Test : IInterface
{
public string Property
{
get
{
return "Property";
}
}
void IInterface.Init()
{
Console.WriteLine("Interface Init.[显示]");
}
public void Show()
{
Console.WriteLine("Interface Show.[隐式]");
}
}
class TestTwo : AbstractClass
{
public override void Show()
{
Console.WriteLine("TestTwo show.");
}
public new void ShowTwo()
{
Console.WriteLine("TestTwo showtwo.");
}
public override void ShowThree()
{
Console.WriteLine("TestTwo showthree.");
}
}
class Stater
{
static void Main()
{
//抽象类
AbstractClass abstractClass = new TestTwo();
abstractClass.Init();
abstractClass.Show();
abstractClass.ShowTwo();//new覆盖,调用父类方法
abstractClass.ShowThree();//override重写,调用子类方法
TestTwo ttObj = new TestTwo();
ttObj.Init();
ttObj.Show();
ttObj.ShowTwo();//new覆盖,调用子类方法
ttObj.ShowThree();//override重写调用子类方法
//接口
IInterface iinterface = new Test();
iinterface.Init();
iinterface.Show();
Test test = new Test();
//test.Init();//Error:显示声明只能接口调用
test.Show();
}
}
abstract class AbstractClass
{
public void Init()
{
Console.WriteLine("AbstractClass Init.");
}
public abstract void Show();
public virtual void ShowTwo()
{
Console.WriteLine("AbstractClass ShowTwo.");
}
public virtual void ShowThree()
{
Console.WriteLine("AbstractClass ShowThree.");
}
}
interface IInterface
{
string Property { get;}
void Init();
void Show();
}
class Test : IInterface
{
public string Property
{
get
{
return "Property";
}
}
void IInterface.Init()
{
Console.WriteLine("Interface Init.[显示]");
}
public void Show()
{
Console.WriteLine("Interface Show.[隐式]");
}
}
class TestTwo : AbstractClass
{
public override void Show()
{
Console.WriteLine("TestTwo show.");
}
public new void ShowTwo()
{
Console.WriteLine("TestTwo showtwo.");
}
public override void ShowThree()
{
Console.WriteLine("TestTwo showthree.");
}
}