在面向对象过程中,知道对象是什么但是总感觉缺乏一种方法来实现面向对象。要实现面向对象就是要用抽象的方法来归纳对象类型,对象的属性和行为以及对象协作关系。
抽象是具体到一般化的过程。
目的是为了把概念和实现的分离以达到应对软件需求的变化的影响。
抽象方法是面向对象中的最基本方法也是最重要的方法之一。在实际使用抽象方法的时候主要是对象分类,规范行为。
抽象使对象具有一般的属性和行为,做到数据与逻辑的有机结合。
抽象是就是要是对象的属性和行为做到“放之四海皆准”的类型。前面的中提到电视机这个类型,有黑白电视机,彩色电视机以及液晶电视机等类型。这些对象实例在某些方面有些差异,但是有一些共同的属性和行为。
抽象实现方法
给对象分类是面向对象实现之方法。
分类有不同的标准与方法,可以根据某个属性,也可以根据行为的差异来分类。
a.基于属性的分类法产生的对象
基于属性的分类法产生的底层对象往往在实现的时候是对象实例,而把上层对象作为对象类型。上面的电视机分类是基于对象的某种属性类型分类的。所以在面向对象编程的时候,是下面的实现。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
public class Tv
{
public string Size { get; set; }
public void Watch()
{
Console.WriteLine("我的尺寸是{0}", Size);
}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
class Program
{
public static void Main(string[] args)
{
// 黑色电视机
Tv blackTv = new Tv();
blackTv.Size = "17寸";
blackTv.Watch();// 彩色电视机
Tv colorTv = new Tv();
colorTv.Size = "32寸";
colorTv.Watch();// 液晶电视机
Tv lcdTv = new Tv();
lcdTv.Size = "22寸";
lcdTv.Watch();Console.Read();
}
}
}所以上面的黑白电视机,彩色电视机和液晶电视机在分析的是对象,但在实现的时候实现成了对象实例。
由于上面的实现把有差异的事物的共性抽象只有Size属性和Watch行为。在某种情况下这种实现是对的。但是也许你会发现电视机是黑白的还是彩色的或者是液晶的信息不能保存。也就是这些电视机是不同的对象实例而已,其他的没有区别。
为了能够使对象实例不但有不同的类型信息,可以使用另外一个Type属性来实现。
使用Type属性来实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
public class Tv
{
public string Size { get; set; }
public string Type { get; set; }
public void Watch()
{
Console.WriteLine("我的尺寸是{0}", Size);
}}
}这样客户端在调用Tv对象的时候可以识别Type属性,也能将对象类型序列化存储。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
class Program
{
public static void Main(string[] args)
{
// 黑色电视机
Tv blackTv = new Tv();
blackTv.Size = "17寸";
blackTv.Type = "黑色电视机";
Console.WriteLine("你正在看的是{0}", blackTv.Type);
blackTv.Watch();// 彩色电视机
Tv colorTv = new Tv();
colorTv.Size = "32寸";
colorTv.Type = "彩色电视机";
Console.WriteLine("你正在看的是{0}", colorTv.Type);
colorTv.Watch();// 液晶电视机
Tv lcdTv = new Tv();
lcdTv.Size = "22寸";
lcdTv.Type = "液晶电视机";
Console.WriteLine("你正在看的是{0}", lcdTv.Type);
lcdTv.Watch();Console.Read();
}
}
}上面的实现方法有明显的弊端,那就是如果用户端把colorTv的Type属性在赋值的时候,赋值成“黑色电视机”也可以,那么就会违反colorTv的定义。
为了克服上面实现的弊端,可以采用面向对象的继承方法来实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
public class Tv
{
protected string type;public Tv()
{
}
public string Size { get; set; }
public void Watch()
{
Console.WriteLine("我是{0},尺寸是{1}", type,Size);
}}
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
class BlackTv:Tv
{
public BlackTv()
{
type = "黑色电视机";
}
}
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
class ColorTv : Tv
{
public ColorTv()
{
type = "彩色电视机";
}
}
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
class LcdTv: Tv
{
public LcdTv()
{
type = "液晶电视机";
}
}
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
class Program
{
public static void Main(string[] args)
{
// 黑色电视机
Tv blackTv = new BlackTv();
blackTv.Size = "17寸";
blackTv.Watch();// 彩色电视机
Tv colorTv = new ColorTv();
colorTv.Size = "32寸";
colorTv.Watch();// 液晶电视机
Tv lcdTv = new LcdTv();
lcdTv.Size = "22寸";
lcdTv.Watch();Console.Read();
}
}
}不过上面的方法也有一些缺陷,比如会造成类炮炸,也就是类太多了。
b.基于行为的分类
上面的电视机对象没有行为的差异,不过液晶电视机能作为电脑的显示终端。所以应该赋予液晶电视机一种行为,暂且命令为ScreenDisplay()。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
class LcdTv: Tv
{
public LcdTv()
{
type = "液晶电视机";
}public void ScreenDisplay()
{
Console.WriteLine("你现在使用的是电脑,我能作为电脑的显示屏");
}
}
}为了调用LcdTv的行为接口,可以定义一个接口IComputerScreen
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TvNs
{
interface IComputerScreen
{
void ScreenDisplay();
}
}
至于如何在编程实践中如何实现抽象方法,请参看