面向对象的三大特性:封装,继承,多态。
一、封装
封装就是把复杂的,变化的东西隐藏,包裹起来,给外界提供简单的,稳定的东西。具体的例子有:
1.把字段封装成属性
2.把多个参数封装成类进行传递
3.将重复的代码放到一个方法中反复调用
4.将几个方法写到一个类中并且在类的实例中调用这些方法
5.将一些具有相同功能的代码放到一个程序集中,对外提供 统一的访问入口等等,这些都是封装的例子。
下面用代码说明第一个例子。
如果我想根据用户的年龄输出不同的名字,代码如下 :
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Person p = new Person(); 6 p.Name = "张三"; 7 Console.WriteLine(p.Name); 8 9 Console.ReadKey(); 10 } 11 } 12 13 public class Person 14 { 15 private int _age = 10; 16 17 private string _name; 18 public string Name 19 { 20 set 21 { 22 if (value.Length > 10) 23 { 24 throw new Exception("名字太长了!"); 25 } 26 else 27 { 28 _name = value; 29 } 30 31 } 32 33 get 34 { 35 if (_age > 12) 36 { 37 return _name; 38 } 39 else 40 { 41 return "小 baby"; 42 } 43 } 44 45 46 } 47 }
在main方法中设置p.Name的时候,先把Name的值传给属性中的value,根据age检验一次,然后把合法的值传给_name。输出调用Name的时候,再检验一次,改变_name的值,并返回,然后输出合法的值。对用户来说,我们只需知道输入和输出的值,没必要关心属性里面做了哪些校验,也没必要输入的值存在哪,输出的值从哪取。属性中也可以做各种修改,比如把用户输入的名字保存到记事本中,检验后再读出来,代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Person p = new Person(); 6 p.Name = "李四"; 7 Console.WriteLine(p.Name); 8 9 Console.ReadKey(); 10 } 11 } 12 13 public class Person 14 { 15 private int _age = 20; 16 17 //private string _name; 18 public string Name 19 { 20 set 21 { 22 if (value.Length > 10) 23 { 24 throw new Exception("名字太长了!"); 25 } 26 else 27 { 28 File.WriteAllText("name.txt",value); 29 } 30 31 } 32 33 get 34 { 35 if (_age > 12) 36 { 37 return File.ReadAllText("name.txt"); 38 } 39 else 40 { 41 return "小 baby"; 42 } 43 } 44 45 46 } 47 }
如果理解属性这个方法?明天反编译看看。
二、继承
1.继承的特性
单根性,传递性。一个类只能继承一个父类。原则上继承是无条件的,但是构造函数不能继承。
2.如何判断一个类能继承另一个类?
用 is a 来判断。比如学生,老师两个类,是否可以抽象同一个父类,人类?分别判断学生和老师是不是人类就行了。
3.易错点
当子类,父类中都只有有参构造函数的时候,实例化子类的时候,程序会报错,因为默认都要先运行父类的无参构造函数,但是这里没有显式写无参构造函数。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Student s = new Student("张三",12); 6 7 Console.ReadKey(); 8 } 9 } 10 11 public class Student:Person 12 { 13 public Student(string name,int age) 14 { 15 this.Name = name; 16 this.Age = age; 17 } 18 public string StuNo { get; set; } 19 } 20 21 public class Teacher:Person 22 { 23 public Teacher(string name,int age) 24 { 25 this.Name = name; 26 this.Age = age; 27 } 28 public double Salary { get; set; } 29 } 30 31 public class Person 32 { 33 //public Person() 34 //{ 35 36 //} 37 public Person(string name, int age) 38 { 39 this.Name = name; 40 this.Age = age; 41 } 42 public string Name { get; set; } 43 public int Age { get; set; } 44 }
如果要指定调用父类的某个具体的构造函数,可以用base关键字;
1 public class Student:Person 2 { 3 public Student(string name):base(name,1) 4 { 5 6 } 7 8 public string StuNo { get; set; } 9 } 10 11 public class Teacher:Person 12 { 13 14 public Teacher(string name,int age) 15 { 16 this.Name = name; 17 this.Age = age; 18 } 19 public double Salary { get; set; } 20 }
如果要调用本类中指定的构造函数,可以用this关键字。
1 public class Teacher:Person 2 { 3 public Teacher(string name):this(name,0) 4 { 5 6 } 7 public Teacher(string name,int age) 8 { 9 this.Name = name; 10 this.Age = age; 11 } 12 public double Salary { get; set; } 13 }
4.识记基本单词
parent class (父类), base class(基类)。child class(子类),derived class(派生类)