封装,继承和多态是面向对象编程的三大特征。
1.封装
封装比较容易理解,封装可以减小工作量。若某个字段需要更改,则只需要更改封装类中相对应的字段。
实现封装的方法:
1.利用函数实现封装
private string name;
public void setName(string Name)//利用方法进行封装
{
name = Name;
}
public string getName()
{
return name;
}
2.利用属性进行封装
private string name;
public string creatName//利用属性进行封装
{
get{ return name;}
set{ name = value;}
}
3.定义一个只读的属性
public class ReadOnly
{
private string ReadName;
public ReadOnly(string a)
{
ReadName = a;
}
public string ReadNameWay//定义一个只读的属性
{
get { return ReadName; }
}
}
同样可以定义一个只写的属性。
2.继承
继承是实现代码重用的重要机制,子类不仅能继承父类已有的特性和能力,还能在此基础上添加新的方法,建立一个新层次的类。
base关键字
base顾名思义即是父类,那么当我们在子类中使用base关键字时,必然和父类中的方法有关。
namespace jicheng
{
public class Person
{
private string name;
private char sex;
private int age;
public Person()
{
Console.WriteLine("this is father's way");
}
public Person(string name, char sex, int age)
{
this.name = name;
this.sex = sex;
this.age = age;
Console.WriteLine("name:{0},sex:{1},age{2}", name, sex, age);
}
public string getAddress()
{
string address = Console.ReadLine();
return address;
}
}
public class Student : Person
{
public Student() : base() { }//调用父类的构造函数
public Student(string a, char b, int c) : base(a, b, c) { }
}
class Program
{
static void Main(string[] args)
{
Student stu1 = new Student("LiMing", 'M', 30);
Console.ReadKey();
}
}
}
输出结果:
this is in father’s class
name:LiMing,sex:M,age30
多重继承的实现
C#不支持多重继承,但引入了接口,一个类可以实现多个接口。
接口本来就是公共的,所以不需要给修饰符
namespace jicheng
{
interface Eat
{
void eat();
}
interface Fly
{
void fly();
}
public class Bird : Eat, Fly
{
public void eat()
{
Console.WriteLine("eat foods");
}
public void fly()
{
Console.WriteLine("fly here");
}
}
class Program
{
static void Main(string[] args)
{
Bird bird = new Bird();
bird.eat();
bird.fly();
Console.ReadKey();
}
}
}
3.多态(通过继承实现的不同对象调用相同的方法,表现出不同的行为)
virtual-----override实现多态以及new的用法
namespace jicheng
{
public class Animal
{
public virtual void print()
{
Console.WriteLine("print in Animal");
}
}
public class Bird : Animal
{
public override void print()
{
Console.WriteLine("print int Brid");
}
}
public class Dog : Animal
{
public override void print()
{
Console.WriteLine("print in Dog");
}
}
public class Cat : Animal
{
public new void print()
{
Console.WriteLine("print in Cat");
}
}
class Program
{
static void Main()
{
Animal []animals = new Animal[4];
animals[0] = new Animal();
animals[1] = new Bird();
animals[2] = new Dog();
animals[3] = new Cat();
for(int i=0;i<4;i++)
{
animals[i].print();
}
Console.ReadKey();
}
}
}
输出结果
print in Animal
print int Brid
print in Dog
print in Animal
由此我们可以看出,使用override实现了对父类方法的重写,覆盖了父类的原有方法。上述代码中,将Bird和Dog类对象转化为Animal类对象时,调用print()方法时调用的是子类重写的方法,而将Cat类对象转化为Animal类对象并调用print()方法时,调用的却是Animal类的方法。
这足以见得new与override的区别。
使用new只是将父类中的该方法隐藏,实际上,new的方法与父类中的原方法是两个不同的方法,只是同名而已。
虽然new不能改变父类方法,但可以实现接口。
假设Base实现了一个接口,当子类用new同时实现该接口时,我们看看会出现什么结果。
namespace jicheng
{
interface IFace
{
void Print();
}
public class Base:IFace
{
public virtual void Print()
{
Console.WriteLine("print in Base");
}
}
public class Child : Base,IFace
{
public new void Print()
{
Console.WriteLine("print in Child");
}
}
class Program
{
static void Main()
{
IFace[] face = new IFace[] { new Base(), new Child(), };
foreach(IFace a in face)
{
a.Print();
}
Console.ReadKey();
}
}
}
虽然使用new无法让父子类中同名的方法联系起来,但通过接口仍然可以实现动态绑定。
而真正实现多态则是通过virtual和override.