本文通过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/