定义:软件实体应该可以扩展,但是不可以修改。
特性:对扩展是开放的,对修改是封闭的。开放即可以操作,关闭即不可以操作。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口声明
{
interface IEatable
{
//接口默认声明名为Public(类的默认声明是private)
//接口中不能有访问修饰符
//由于接口不能有字段,所以属性经常被写作自动属性
//声明属性
string Name
{
get;
set;
}
//声明方法,方法中不能包含方法体
void Write(); //无返回值
string Read(); //有返回值
}
}
老鹰(eagle)、麻雀(sparrow)鸵鸟(ostrich)都是鸟类,根据三者的共性,提取出鸟类作为父类;并且各自具有各自的特点,老鹰吃小鸡,麻雀吃粮食,鸵鸟吃青草
老鹰和麻雀都会非,如何实现这个飞功能
实现方法:
程序入口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口的实现与继承
{
class Program
{
static void Main(string[] args)
{
//实现多态
IFlyable[] flys = { new Sparrow(), new Eagle(),new Swan(), new Balloon() };
foreach (IFlyable outFly in flys) outFly.Fly();
Console.ReadLine();
}
}
}
接口声明
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口的实现与继承
{
interface IFlyable
{
void Fly();
}
}
抽象类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口的实现与继承
{
abstract class Bird
{
public abstract void Eat();
}
}
Eagle继承抽象类及接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口的实现与继承
{
class Eagle:Bird,IFlyable
{
public void Fly()
{
Console.WriteLine("我是老鹰我会飞");
}
public override void Eat()
{
Console.WriteLine("我是老鹰专吃小鸡");
}
}
}
Sparrow继承抽象类及接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口的实现与继承
{
class Sparrow:Bird,IFlyable
{
public void Fly()
{
Console.WriteLine("我是麻雀我会飞");
}
public override void Eat()
{
Console.WriteLine("我是麻雀,我吃粮食");
}
}
}
Sparrow继承抽象类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口的实现与继承
{
class Ostrich:Bird
{
public override void Eat()
{
Console.WriteLine("我是鸵鸟,只吃草");
}
}
}
Swan扩展(继承抽象类及接口)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口的实现与继承
{
class Swan:Bird,IFlyable
{
public override void Eat()
{
Console.WriteLine("我是天鹅,我吃鱼");
}
public void Fly()
{
Console.WriteLine("我是天鹅我会费");
}
}
}
扩展:Balloon继承接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口的实现与继承
{
class Balloon:IFlyable
{
public void Fly()
{
Console.WriteLine("我是气球我会飞");
}
}
}
隐式实现接口:即可用接口调用方法,也可用具体类调用方法
显式实现接口:实现接口的方法前不能用访问修饰符public, 必须显式指定接口名称
返回值类型 接口名称.接口方法
只能是通过接口嗲用,而不能通过具体类调用
同时隐式实现接口和显式实现接口:这样完成对弈个几口成员提供多份实现提,访问是可以永磊的实例和接口的引用来分别调用这两种实现实体。显式才是真正的接口实现方式
结论:当显式实现方式存在时,隐式实现方式就失效了。但这不能标识显式实现方式就不好,当一个类实现的多个接口中具有相同的方法时,用显式方式来专门实现某个接口的方法时,就显得非常有用!
Main方法——接口调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _4_显示实现接口
{
class Sparrow:Bird,Iflyable
{
public void Fly()
{
Console.WriteLine("(隐式实现)我是麻雀我会飞");
}
void Iflyable.Fly()
{
Console.WriteLine("(显式实现)我是麻雀我会飞");
}
public override void Eate()
{
Console.WriteLine("我是麻雀,我吃粮食");
}
}
}
接口1声明fly()方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _4_显示实现接口
{
interface Iflyable
{
void Fly();
}
}
接口2声明fly()方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _4_显示实现接口
{
interface Iflyable
{
void Fly();
}
}
抽象类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _4_显示实现接口
{
abstract class Bird
{
public abstract void Eate();
}
}
隐式实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _4_显示实现接口
{
class Eagle:Bird,Iflyable
{
public override void Eate()
{
Console.WriteLine("我是老鹰,我吃小鸡");
}
public void Fly()
{
Console.WriteLine("我是老鹰,我会飞");
}
}
}
显式实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _4_显示实现接口
{
class Balloon:Iflyable,IFllyable2
{
//显示实现接口
void Iflyable.Fly()
{
Console.WriteLine("我是Iflyable中的飞");
}
void IFllyable2.Fly()
{
Console.WriteLine("我是IFllyable2中的飞");
}
}
}
隐式和显式同时存在
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _4_显示实现接口
{
class Sparrow:Bird,Iflyable
{
public void Fly()
{
Console.WriteLine("(隐式实现)我是麻雀我会飞");
}
void Iflyable.Fly()
{
Console.WriteLine("(显式实现)我是麻雀我会飞");
}
public override void Eate()
{
Console.WriteLine("我是麻雀,我吃粮食");
}
}
}
public class abstract Fly
{
public abstract void Flys(); 抽象方法中没有方法体
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5_抽象类与抽象方法
{
public abstract class Class1
{
//抽象类与抽象方法声明中必须包含abstract,并且抽象方法不能有方法体
//抽象类的声明就是为了实现派生或者继承,所以我们不能将它同时标记为sealed
public abstract void Methond();
public abstract void Methond2();
//抽象类中可以包含非抽象方法
public void Add(int a, int b)
{
Console.WriteLine(a+b);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5_抽象类与抽象方法
{
public abstract class Class2:Class1
{
//因为class1中有两个抽象方法,而class2中仅实现一个抽象方法,此时class2也必须声明为抽象类
public override void Methond()
{
throw new NotImplementedException();
}
}
}
定义:方法前abstract就被称为抽象方法,抽象方法不提供任何实际实现
注意:
抽象方法必须在抽象类中声明
不能使用static private virtual修饰符
方法不能有任何可执行程序,哪怕是方法体{}
重写抽象方法时采用override
实例:Pow类定义了一个求幂对象的抽象概念。Pow类方法时抽象的,PowB类和PowC类是Pow具体实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5_抽象类与抽象方法
{
class Program
{
static void Main(string[] args)
{
PowB myPowB = new PowB();
myPowB.PowMethond(2,10);
PowC myPowC = new PowC();
myPowC.PowMethond(2,10);
Console.ReadKey();
//abstract与virtual
//共同点:都可以通过overriede来实现对原有方法的重写
//abstract没有自己的实现,virtual有自己的实现
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5_抽象类与抽象方法
{
public abstract class Pow
{
public abstract void PowMethond(int x, int y);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5_抽象类与抽象方法
{
class PowB:Pow
{
public override void PowMethond(int x, int y)
{
int pow = 1;
for (int i = 1; i <= y; i++)
{
pow *= x;
}
Console.WriteLine("求幂的结果是"+pow);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5_抽象类与抽象方法
{
class PowC:Pow
{
public override void PowMethond(int x, int y)
{
Console.WriteLine("求幂的结果是"+ System.Math.Pow(x, y));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 密封类和密封方法
{
//如果一个类不希望将来在使用过程被继承或被派生,这时候可以采用关键字sealed
//虚方法virtual 抽象方法abstract存在就是为了派生,所以不能存在在密封类中。
sealed class Class2
{
}
}
定义:用修饰符sealed进行标记的方法
作用:使用sealed修饰符可以以防止派生类进一步重写该方法
注意:如果实例方法声明包含sealed修饰符,则它必须也包含override修饰符
要在方法中使用sealed关键字,必须现在基类上将其声明为重写。如果基类上不希望有重写的方法或属性,就不要将其声明为virtual
密封类除了不能被继承外,其他与非密封类一样,密封方法则必须通过重写基类中的虚方法来实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 密封类和密封方法
{
class Program
{
static void Main(string[] args)
{
Class2 mymethond = new Class2();
mymethond.Write();
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 密封类和密封方法
{
public class Class1
{
public virtual void Write()
{
Console.WriteLine("这是一个未密封的虚方法");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 密封类和密封方法
{
//如果一个类不希望将来在使用过程被继承或被派生,这时候可以采用关键字sealed
//虚方法virtual 抽象方法abstract存在就是为了派生,所以不能存在在密封类中。
public class Class2:Class1
{
public sealed override void Write()
{
Console.WriteLine("这是一个密封的方法");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 密封类和密封方法
{
class Class3:Class2
{
// 不能重写密封方法
//public override sealed void Write()
//{
//}
}
}
多态实现的方法:
虚方法:可以抽象出一个类,并且抽象出一个类需要有实现。例如员工 项目经理 工作计划(员工和项目经理都有工作计划,且项目经理属于员工,员工工作计划也要有实现)
抽象类:可以抽象出一个父类,但是抽象类需要有一个方法,但是实现方法的途径不确定(例如:老鹰,麻雀、鸵鸟都属于鸟,且都需要吃,但吃的东西不同,需要根据具体对象确定。所有鸟就是抽象类,抽象方法——方法没有具体实现(吃什么不知道)通过具体派生类实现具体方法——吃什么)
接口:不能抽象出一个父类,但是可找到他们共同的特点,也就是共同的行为能力(共同的属性、方法),接口表现的是一种能力一种规范
实例:真毛不会说话,Tom猫会说话,kitty猫会说话
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 本章小结及任务实施
{
class Program
{
static void Main(string[] args)
{
ISayWords mycat1 = new TomCat();
mycat1.Say();
ISayWords myCat2 = new KittyCat();
myCat2.Say();
RealCat mycat3 = new RealCat();
mycat3.Say();
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 本章小结及任务实施
{
interface ISayWords
{
void Say();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 本章小结及任务实施
{
class RealCat
{
public void Say()
{
Console.WriteLine("我是真猫,我不会说话");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 本章小结及任务实施
{
class TomCat:ISayWords
{
public void Say()
{
Console.WriteLine("我是Tom猫,我会学别人说话");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 本章小结及任务实施
{
class KittyCat:ISayWords
{
public void Say()
{
Console.WriteLine("我是kitty猫,我自己会说话");
}
}
}