设计模式学习笔记二:面向对象基础四之抽象类和接口
抽象类
c#允许把类和方法声明为abstract,即抽象类和抽象方法。你会发现Animal类其实根本就不能被实例化,一只猫张什么样,你可以想象,一只动物张什么样,你能想象吗?
抽象类需要注意的几点:一,抽象类不能实例化;抽象方法是必须被子类重写的方法;如果类中包含有抽象方法,那么类必须定义为抽象类,不论其是否包含有其他方法。
我们应该考虑让抽象类拥有尽可能多的代码,尽可能少的数据。
抽象类通常代表一个抽象概念,他提供一个继承的出发点当设计一个抽象类时,一定是用来继承的,所以,在一个以继承关系形成的等级结构里面,树叶节点应当是具体类,而树枝节点应当均是抽象类。
抽象类:
子类:
接口(interface):
接口是把隐式公共方法和属性组合起来,来分装特定功能的一个集合。一旦类实现了接口,类就可以支持接口所指定的所有属性和成员。声明接口在语法上和声明抽象类完全相同,但不允许提供接口中任何成员的执行方式。接口不能被实例化,不能有构造方法和字段,不能有修饰符。不能声明虚拟的或静态的。实现接口中的类必须要实现接口中的所有方法和属性。
一个类可以支持多个接口,多个类可以支持相同的接口。接口的命名前面要加‘I’,这是规范。接口用interface声明,而不是class,接口中的方法和属性前面不能有修饰符、方法没有方法体。
看下面机器猫变东西的例子:
变东西接口:
从表象上看抽象类可以给出一些成员的实现,接口却不包含成员的实现;抽象类的抽象成员可以被子类部分实现,接口的成员需要实现类完全实现;一个类只能继承一个抽象类,但可以实现多个接口。
也可以从以下几个方面来区别抽象类与接口:第一,类是对对象的抽象;抽象类是对类的抽象;接口是对行为的抽象。第二,如果行为跨越不同类的对象,可使用接口,对于一些相似的类对象,用继承抽象类。第三,从设计角度看,抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类,而接口是根本不知子类的从在,方法如何实现还不确认,预先定义。
c#允许把类和方法声明为abstract,即抽象类和抽象方法。你会发现Animal类其实根本就不能被实例化,一只猫张什么样,你可以想象,一只动物张什么样,你能想象吗?
抽象类需要注意的几点:一,抽象类不能实例化;抽象方法是必须被子类重写的方法;如果类中包含有抽象方法,那么类必须定义为抽象类,不论其是否包含有其他方法。
我们应该考虑让抽象类拥有尽可能多的代码,尽可能少的数据。
抽象类通常代表一个抽象概念,他提供一个继承的出发点当设计一个抽象类时,一定是用来继承的,所以,在一个以继承关系形成的等级结构里面,树叶节点应当是具体类,而树枝节点应当均是抽象类。
抽象类:
/// <summary>
///父类
/// </summary>
public abstract class Animal
{
protected string name = "";
protected int shoutNum = 3;
public Animal(string name)
{
this.name = name;
}
public Animal()
{
this.name = "无名";
}
/// <summary>
/// 抽象方法
/// </summary>
/// <returns></returns>
public abstract string Shout();
}
///父类
/// </summary>
public abstract class Animal
{
protected string name = "";
protected int shoutNum = 3;
public Animal(string name)
{
this.name = name;
}
public Animal()
{
this.name = "无名";
}
/// <summary>
/// 抽象方法
/// </summary>
/// <returns></returns>
public abstract string Shout();
}
子类:
/// <summary>
/// Cat子类
/// </summary>
public class Cat:Animal
{
public Cat()
: base()
{ }
public Cat(string name)
: base(name)
{ }
/// <summary>
/// 重写父类的抽象方法
/// </summary>
/// <returns></returns>
public override string Shout()
{
string result = "";
for (int i = 0; i < shoutNum; i++)
{
result = result + "嘧,";
}
return "我的名字叫" + name + " " + result;
}
}
/// Cat子类
/// </summary>
public class Cat:Animal
{
public Cat()
: base()
{ }
public Cat(string name)
: base(name)
{ }
/// <summary>
/// 重写父类的抽象方法
/// </summary>
/// <returns></returns>
public override string Shout()
{
string result = "";
for (int i = 0; i < shoutNum; i++)
{
result = result + "嘧,";
}
return "我的名字叫" + name + " " + result;
}
}
接口(interface):
接口是把隐式公共方法和属性组合起来,来分装特定功能的一个集合。一旦类实现了接口,类就可以支持接口所指定的所有属性和成员。声明接口在语法上和声明抽象类完全相同,但不允许提供接口中任何成员的执行方式。接口不能被实例化,不能有构造方法和字段,不能有修饰符。不能声明虚拟的或静态的。实现接口中的类必须要实现接口中的所有方法和属性。
一个类可以支持多个接口,多个类可以支持相同的接口。接口的命名前面要加‘I’,这是规范。接口用interface声明,而不是class,接口中的方法和属性前面不能有修饰符、方法没有方法体。
看下面机器猫变东西的例子:
变东西接口:
/// <summary>
/// 变东西接口
/// </summary>
public interface IChange
{
string ChangeThing(string thing);
}
机器猫类:/// 变东西接口
/// </summary>
public interface IChange
{
string ChangeThing(string thing);
}
/// <summary>
/// 机器猫继承于猫,并实现了IChange接口,注意Cat和IChange是用‘,’隔开的
/// </summary>
public class MachineCat : Cat, IChange
{
public MachineCat()
: base()
{ }
public MachineCat(string name)
: base(name)
{ }
/// <summary>
/// 实现接口
/// </summary>
/// <param name="thing"></param>
/// <returns></returns>
public string ChangeThing(string thing)
{
return base.Shout() + "我有万能的口袋,我能变出"+thing;
}
}
哈哈,机器猫要变东西啦:/// 机器猫继承于猫,并实现了IChange接口,注意Cat和IChange是用‘,’隔开的
/// </summary>
public class MachineCat : Cat, IChange
{
public MachineCat()
: base()
{ }
public MachineCat(string name)
: base(name)
{ }
/// <summary>
/// 实现接口
/// </summary>
/// <param name="thing"></param>
/// <returns></returns>
public string ChangeThing(string thing)
{
return base.Shout() + "我有万能的口袋,我能变出"+thing;
}
}
public class AnimalChange
{
private string changeMatch()
{
MachineCat mcat = new MachineCat("叮当");
return mcat.ChangeThing("各式各样的东西!");
}
}
抽象类与接口区别:{
private string changeMatch()
{
MachineCat mcat = new MachineCat("叮当");
return mcat.ChangeThing("各式各样的东西!");
}
}
从表象上看抽象类可以给出一些成员的实现,接口却不包含成员的实现;抽象类的抽象成员可以被子类部分实现,接口的成员需要实现类完全实现;一个类只能继承一个抽象类,但可以实现多个接口。
也可以从以下几个方面来区别抽象类与接口:第一,类是对对象的抽象;抽象类是对类的抽象;接口是对行为的抽象。第二,如果行为跨越不同类的对象,可使用接口,对于一些相似的类对象,用继承抽象类。第三,从设计角度看,抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类,而接口是根本不知子类的从在,方法如何实现还不确认,预先定义。