本文通过c#来理解面向对象编程:封装、继承、多态
翠花,上程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test1
{
//定义类(类就是具有相同的属性和功能的对象的抽象的集合)
//动物(abstract:使得不能直接创建animal类) public abstract class Animal { private int age; private bool hair; public bool Hair { get { return hair; } set { hair = value; } } public int Age { //动物的寿命都大于0 get { return age; } set { //value是隐式参数 if(value < 0) { Console.WriteLine("赋值错误"); throw (new ArgumentOutOfRangeException("AgeIntPropery", value, "年龄必须大于0")); } age = value; } } //基类构造函数 public Animal() { Console.WriteLine("我是动物"); } //基类声明virtual或abstract才能被重写 public virtual void Voice() { Console.WriteLine("动物开始发出声音"); } } //马 public class Horse : Animal { //子类构造函数 public Horse() { Console.WriteLine("我是马"); Hair = true; } public override void Voice() { //调用基类方法 base.Voice(); Console.WriteLine("马发出。。嘶。。嘶。。"); } } //羊 public class Sheep : Animal { //子类构造函数 public Sheep() { Console.WriteLine("我是羊"); Hair = true; } public override void Voice() { //调用基类方法 base.Voice(); Console.WriteLine("羊发出。。,米啊。。米啊。"); } } //鱼 public class Fish : Animal { //子类构造函数 public Fish() { Console.WriteLine("我是鱼"); Hair = false; } //当日到了鱼这里可以选择不重载 public override void Voice() { //调用基类方法 base.Voice(); Console.WriteLine("老子不会说话"); } } class Program { static void Main(string[] args) { Horse horse = new Horse(); horse.Age = 2; Console.WriteLine("马的年龄为;{0}",horse.Age); Console.WriteLine("毛:{0}", horse.Hair); horse.Voice(); Sheep sheep = new Sheep(); sheep.Age = 1; Console.WriteLine("马的年龄为:{0}", sheep.Age); Console.WriteLine("毛:{0}", sheep.Hair); sheep.Voice(); Fish fish = new Fish(); fish.Age = 2; Console.WriteLine("鱼的年龄为:{0}", fish.Age); Console.WriteLine("毛:{0}", fish.Hair); fish.Voice(); Console.Read(); } }}
一、封装
封装的意义:隐藏类的内部细节。(定义必要的私有数据字段)
private int age;
private bool hair;
public bool Hair
{
get { return hair; }
set { hair = value; }
}
public int Age
{
//动物的寿命都大于0
get { return age; }
set
{
//value是隐式参数
if(value < 0)
{
Console.WriteLine("赋值错误");
throw (new ArgumentOutOfRangeException("AgeIntPropery", value, "年龄必须大于0"));
}
age = value;
}
}
程序中定义公共类型的弊端:
则后面可以随意设置age的大小,设置成负的也可以。
定义私有字段解决了什么:
通过Age属性(公共)来对age(私有)进行间接操作,这样就像给age包了一层衣服的一样。隐藏了age的判定的细节,对外提供了age属性接口(age字段(间接))
二、继承
继承的意义:我们可以将有公共属性的几个类抽象成一个基类,然后每个类再继承这个基类实现各自的功能。本质是为了复用父类程序
例子中马、羊、鱼都是动物,所以可以抽象动物基类。子类能够获得父类的所有成员(构造函数、析构函数除外)。
继承是一种is关系:A是B,则A能继承B
三、多态
多态的意义:相同类型对象调用相同的方法却表现出不同行为。(继承解决了相同行为的问题,多态解决了不同行为的问题)
接口是can的关系:A
四、子类初始化顺序
这个大家可以debug一下,就清楚了
1.初始化类的实例字段
2.调用基类构造函数
3.调用子类构造函数
参考:http://www.cnblogs.com/zhili/