Learning hard C#学习笔记——读书笔记 03

  • Learning hard C#学习笔记——读书笔记 03已关闭评论
  • 122 次浏览
  • A+
所属分类:.NET技术
摘要

C# 是面向对象的语言,每次到这里就会有一个问题,什么是对象,其实一句话就可以解释,那就是——万物皆是对象,这句话就像 “如来”一样抽象,其实,我们无须在这上面耗费太大的精力,我们随着学习的深入,对象的概念自然会深入到脑海中

C# 是面向对象的语言,每次到这里就会有一个问题,什么是对象,其实一句话就可以解释,那就是——万物皆是对象,这句话就像 “如来”一样抽象,其实,我们无须在这上面耗费太大的精力,我们随着学习的深入,对象的概念自然会深入到脑海中

所有面向对象的编程语言都有以下三个基础特征

  • 封装——把客观的事物封装成类,并将类内部实现隐藏
  • 继承——通过继承可以复用父类的代码
  • 多态——允许将子对象赋值给父对象的一种能力

1.封装

封装是把类的内部数据隐藏,不让对象实例直接对齐操作,C# 提供属性机制来对内部的状态进行操作,在 C# 中封装可以通过public、private、protected、internal等关键字来体现

为什么要进行封装呢?

封装是一种程序内部的保护机制,保护数据的完整性,

例如:我定义一个人的类,创建了它的对象,将其内部的age属性赋值为 -5 ;但是我们都知道,人的年龄是没有-5的,这种随意的赋值,就破坏了数据的完整性

解决上面的情况,就需要使用下面的这种方式

public class Person  {     private string _name;     private int _age;        public string Name {         get { return _name; }         set { _name = value; }     }        public int Age {         get { return _age; }         set {              if(value < 0 || value > 120)              {                 throw(new ArgumentOutOfRangeException("AgeIntPropery",value,"年龄必须在0~120之间"));             }else {                 _age = value;             }         }     } } 

2.继承

在 C# 中一个类可以继承另外一个已有的类,(密封类除外),被继承的类被称为基类或者父类

为什么需要继承呢?

继承的作用主要是为了复用基类的内容,但是继承也有自己的缺点,就是耦合性太大,要结合场景来使用

class Program  {     static void Main(string[] args)     {         Horse horse = new Horse();         horse.Age = 2;            Sheep sheep = new Sheep();         sheep.Age = 1;         Console.WriteLine("羊的年龄:{0}",sheep.Age);         Console.Read();      } }  public class Animal {     private int _age;     public int Age     {         get { return _age; }         set          {             if(value < 0 || value > 10)             {                 throw (new ArgumentOutOfRangeException("AgeIntProperty",value,"年龄必须在0-10之间"))             }             _age = value;         }     } }  public class Horse:Animal{}  public class Sheep:Animal{} 

2.1 密封类

密封类不能被另外一个类继承,如果强行继承,就会编译错误

public sealed class SealedClass {     // 在这里定义类成员 }  // 下面的代码会编译错误 public class Test:SealedClass{ } 

2.2 子类初始化的顺序

继承之后,我们不仅仅会调用子类的构造函数,还会调用基类的构造函数,子类的初始化顺序如下:

  1. 初始化类的实例字段
  2. 调用基类的构造函数,如果没有指明基类,则调用System.Object构造函数
  3. 调用子类的构造函数

class Program  {     static void Main(string[] args)     {         Horse horse = new Horse();         horse.Age = 2;            Sheep sheep = new Sheep();         sheep.Age = 1;         Console.WriteLine("羊的年龄:{0}",sheep.Age);         Console.Read();      } }  public class Animal {     // 2.初始化基类的成员变量     private int _age;     public int Age     {         get { return _age; }         set          {             if(value < 0 || value > 10)             {                 throw (new ArgumentOutOfRangeException("AgeIntProperty",value,"年龄必须在0-10之间"));             }             _age = value;         }     }      // 3.调用基类的构造     public Animal() {      } }  public class Horse:Animal{     // 1.先初始化     private string run;      // 4.调用子类构造     public Horse() {      }   }  public class Sheep:Animal{     private string eat;        public Sheep() {      } } 

3.多态

由于有了继承,子类需要复写父类中的方法,来实现子类特有的行为,这样的技术在面向对象的编程就是多态,多态即相同类型对象调用相同的方法,却表现出不同的行为

3.1 使用 virtual 和 override 关键字来实现方法重写

只有基类声明为 virtual 或 abstract 时,才可以被派生类重写;而子类想要改变虚方法的实现行为,只能使用override关键字

class Program {     static void Main(string[] args)     {         Animal horse = new Horse();         horse.Voice();          Animal sheep = new Sheep();         // 相同类型对象,调用相同的方法,表现出的行为不同         sheep.Voice();         Console.Read();     } }  public abstract class Animal {     private int _age;     public int Age     {         get { return _age; }         set         {             if (value < 0 || value > 10)             {                 throw (new ArgumentOutOfRangeException("AgeIntProperty", value, "年龄必须在0-10之间"));             }             _age = value;         }     }     public virtual void Voice()     {         Console.WriteLine("动物开始发出声音");     } }  public class Horse : Animal {     public override void Voice()     {         // 调用基类的方法         base.Voice();         Console.WriteLine("?叫");     } }  public class Sheep : Animal {     public override void Voice()     {         base.Voice();         Console.WriteLine("羊叫~~~咩");     } } 

Learning hard C#学习笔记——读书笔记 03

3.2 阻止派生类重写虚成员

用sealed关键字可以防止一个类被其它类继承,同时也可以使用sealed关键字来阻止派生类重写虚成员。

public class Horse:Animal {     public sealed override void Voice()     {         base.Voice();         Console.WriteLine("马叫,撕");     } } 
public class Test:Horse {     // 编译错误,因为此时,Voice在Horse中sealed修饰,定义为密封的     public override void Voice(){     } } 

3.3 使用新成员隐藏基类成员

public class Animal {     public void Eat() {         Console.WriteLine("动物吃的方法")     } }  public class Horse:Animal {     // 这里如果要隐藏掉基类中的Eat方法需要使用new关键字     public new void Eat() {         Console.WriteLine("马吃的方法")     } } 

如果我们需要在子类中定义与基类同名的方法则需要使用new关键字,将基类成员隐藏

class Program {     static void Main(string[] args) {         Horse horse = new Horse();         horse.Eat();            ((Animal)horse).Eat();         Console.Read();     } } 

所有子类的父类:System.object

在 C# 中,所有类都派生于System.object,如果定义的类没有指定任何基类,编译器就会把Object当作它的基类

Learning hard C#学习笔记——读书笔记 03