面向对象三大特征详解

张开发
2026/4/9 17:07:46 15 分钟阅读

分享文章

面向对象三大特征详解
一、封装1.介绍封装在现实生活中的理解就是将一些东西打包放进盒子中并将盒子封口已到达保护盒子内部事务的目的。在面向对象中封装是指将数据和方法封装在一个类中对外部隐藏内部实现的细节只暴露对外部可见的接口。通过封装可以实现数据的保护和安全性。封装通过访问修饰符来实现。通常会对类中的数据进行封装保证数据的安全性。2.字段和属性在C#中‌字段和属性是两种不同的数据成员‌它们各自具有特定的用途和特性。‌2.1 字段字段是类的成员变量‌可以使用任意的访问权限修饰符进行修饰。例如字段可以是公有的‌public‌‌这意味着它们可以从类的外部访问和修改‌但这通常违背了封装的原则。‌字段也可以是私有的‌private‌‌这种情况下‌通常需要通过属性或其他方法来访问和修改字段的值符合封装的原则。2.2 属性属性通常用于实现数据的封装‌确保外部代码只能通过预定义的方式访问和修改数据‌而不是直接操作字段。‌属性提供了一种更灵活的方式来访问类的数据成员‌它结合了取值‌get‌和赋值‌set‌方法‌可以控制对字段的访问。‌属性可以是自动实现的‌即编译器会自动为属性生成一个隐式的字段来存储值‌也可以是非自动实现的‌这种情况下需要显式地定义getter和setter方法。‌3. 实现封装私有的字段通常以_开头其它遵循小驼峰命名法。公开的属性通常遵循大驼峰命名法。选中字段名Ctrl R E 快速生成get/set方法。//定义私有字段 private string _name; private int _age; //公开属性 //ALT ENTER 选中 封装字段 public string Name{get name; set name value;} public int Age{get age; set age value}二、继承1.介绍继承顾名思义就是从上一位手中将一个东西传承下来。在编程角度继承就涉及到了类与类之间的关系。如果多个类中存在相同的方法、字段、属性则可以考虑将相同方法、字段、属性抽取到父类中减少代码冗余再通过继承关系子类对象可以直接调用父类中的方法进而可以避免反复编写相同逻辑的代码。2.使用原则虽然从语法角度上讲只要有公共的就可以提取到父类中。但是按照面向对象思想应该把具有继承关系的两个类设计成父子类。如可以把人类当做男人的父类但是不可以把牛设计为男人的父类。(代码依旧可以运行但我们编写代码要讲现实逻辑)3.语法格式class A : B{}以上代表A类继承了B类也可以说B类派生出了A类注意A类 继承 B类A类可以直接使用B类中可以被继承的属性和方法。父类中应根据职责封装子类共有的属性和方法。C#中为单继承只能有一个直接父类。例如图所示我们创建了一个Animal类具有两个私有的字段并提供类公开的属性在实例化之后就可以操作字段的值写了两个输出方法我们再创建两个子类Dog和Cat类分别继承Animal类类中定义了本类的自己的方法但字段和属性继承自父类此时子类实例化之后可以直接使用父类的字段来赋值在main方法中创建子类对象通过类名.属性名为字段赋值如图中的dog.Name 旺财; 就是通过子类对象.Name属性调用父类中的Set方法属性本质为Get 、Set方法来给_name字段赋值4.sealed在C#中一个类可以被声明为sealed,这意味着这个类不能被继承---- class sealed A{}三、方法重写1.介绍方法重写是以继承为基础从父类中继承来的方法无法满足子类需求时子类可以重写从父类中继承的方法方法重写让程序代码更加灵活注意子类重写了父类中的方法后调用时只调用子类中重写后的方法。重写的方法必须与父类方法的签名完全相同即具有相同的名称、参数列表和返回类型。2.分类2.1 virtual 方法父类中的方法使用 virtual 修饰子类可以重写也可以不重写。用override修饰的为已经实现的方法即是虚方法。父类中定义的public virtual void ToString(){方法体;}子类中重写的public override void ToString(){方法体();}2.2 abstract 方法2.2.1 介绍类中的方法使用 abstract 修饰方法必须没有实现没有方法体即是抽象方法。2.2.2 抽象类使用abstract修饰类。一个类中有抽象方法这个类必须为抽象类。抽象类中可以有非抽象方法。抽象类有构造函数但是抽象类不能创建对象。抽象方法不能使用private访问权限修饰符使用private修饰之后的类无法被继承子类需要重写该方法。5.子类继承抽象类后必须把抽象类的所有抽象方法重写除非子类也是一个抽象类。3. 方法重写与方法重载英文位置不同作用不同重载overload同一个类中在一个类里面的一种行为方法名可以相同提高可读性可维护性。。重写override子类和父类间父类方法无法满足子类的要求子类通过方法重写满足要求。四、base关键字1. 介绍在c#中base关键字用于访问当前类的基类成员这包括基类的字段、属性、方法、构造函数等。等同于java中的super关键字2.访问基类成员namespace Demo01 { internal class Animal { public string _name 动物; public virtual void Play() { Console.WriteLine(Animal中的Play方法); } } class Bird : Animal { public string _name 鸟; public override void Play() { Console.WriteLine(Bird中的Play方法); } public void Test() { Console.WriteLine(_name); //鸟 Play(); //Bird中的Play方法 Console.WriteLine(base._name); //动物 base.Play(); //Animal中的Play方法 } } }3.this与base关键字的区别1.this用于引用当前对象的实例a.可以通过this关键字来访问当前对象的成员每个实例方法都有一个隐式的this参数。这是从底层实现角度说的。当你调用实例方法时Person person new Person(张三, 25); person.Introduce(); // 调用实例方法编译器实际上在幕后做了类似这样的事情// 概念上实例方法被编译成类似这样的静态方法 public static void Introduce(Person this) // this 作为隐藏参数传递 { Console.WriteLine($我是 {this.name}今年 {this.age} 岁); } // 调用时 Person.Introduce(person); // 将对象引用作为参数传递b.this访问的成员在本类中没有时才会访问父类的成员先查找当前类包括当前类中定义的成员如果当前类没有再向父类查找一直向上到 Object但如果当前类有同名成员会隐藏hide父类成员public class Animal { public string Name 动物; public void Eat() { Console.WriteLine(动物吃东西); } public virtual void Speak() { Console.WriteLine(动物叫); } } public class Dog : Animal { public new string Name 狗; // 使用 new 隐藏父类的 Name public new void Eat() // 隐藏父类的 Eat 方法 { Console.WriteLine(狗啃骨头); } public override void Speak() // 重写父类的 Speak 方法 { Console.WriteLine(汪汪叫); } public void Test() { // this 访问时优先使用 Dog 类自己的成员 Console.WriteLine(this.Name); // 输出: 狗Dog 的 Name this.Eat(); // 输出: 狗啃骨头Dog 的 Eat this.Speak(); // 输出: 汪汪叫Dog 的 Speak } }2.base用于引用当前类的父类实例对象a.可以通过base关键字来访问父类对象中的成员。五、接口1. 介绍接口Interface是一种定义规范而不是定义行为具体的实现引用类型。接口定义了一个对象或者类要实现的操作它可以定义一组方法、属性。 使用 interface 关键字来定义接口。接口定义中只包含属性和方法的声明而没有实际的方法实现或字段。可以把一个接口看做是一组公共的属性和方法的规范。由于C#中继承是单继承的接口为多继承在某些方面可以弥补单继承的不足。2.特点1. 接口存在的意义就是制定规范。2. 接口没有构造函数不能创建对象。3. 接口中属性方法不允许添加访问权限修饰符默认为public。4. 接口与接口之间可以多继承。5. 类与接口之间可以多实现。6. 实现类实现了接口后必须将接口中所有抽象方法都实现。3. 使用原则接口使用interface关键字声明它与类的声明类似。接口声明默认是 public 的。按照约定接口名称以大写字母I开头。接口中的属性是隐式public。接口中的方法隐式为public公开 abstract(抽象类)。4.语法格式4.1定义接口[public | internal] interface 接口名{返回值类型 方法名([形参列表]);}internal interface IMyInterface { void Play(); }4.2 实现接口[public | internal] class 类名 : 接口名{返回值类型 方法名([形参列表])​ {方法体;​ }}internal interface IMyInterface { void Play(); } class MyClass : IMyInterface { public void Play() { } }可以一次实现多个接口[public | internal] class 类名 : 接口名接口名internal interface IMyInterface { void Play(); } internal interface IMyInterface1 { void Play1(); } class MyClass : IMyInterface, IMyInterface1 { public void Play() { } public void Play1() { } }不同于类接口可以多重继承类只能多层继承六、多态1. 介绍面向对象三大特征之一多态。调用同一个父类|接口中的方法由于子类|实现类不同可能会有不同的行为。2. 使用原则1. 以继承继承类|实现实现接口为前提。2. 多态 可以 增加代码的灵活度。3. 是调用方法的技巧不会影响到类|接口的内部设计。3. 代码示例3.1 正常类多态internal class Car { public virtual void drive() { } } class Benz : Car { public override void drive() { Console.WriteLine(Benz实现的drive方法); } } class Bmw : Car { public override void drive() { Console.WriteLine(Bmw实现的drive方法); } } class Audi : Car { public override void drive() { Console.WriteLine(Audi实现的drive方法); } } internal class Program { static void Main(string[] args) { Car car1 new Benz(); car1.drive(); Car car2 new Bmw(); car2.drive(); Car car3 new Audi(); car3.drive(); Console.ReadKey(); } }3.2 抽象类多态internal abstract class Car { public abstract void drive(); } class Benz : Car { public override void drive() { Console.WriteLine(Benz实现的drive方法); } } class Bmw : Car { public override void drive() { Console.WriteLine(Bmw实现的drive方法); } } class Audi : Car { public override void drive() { Console.WriteLine(Audi实现的drive方法); } } internal class Program { static void Main(string[] args) { Car car1 new Benz(); car1.drive(); Car car2 new Bmw(); car2.drive(); Car car3 new Audi(); car3.drive(); Console.ReadKey(); } }3.3 接口多态internal interface ICar { void drive(); } class Benz : ICar { public void drive() { Console.WriteLine(Benz实现的drive方法); } } class Bmw : ICar { public void drive() { Console.WriteLine(Bmw实现的drive方法); } } class Audi : ICar { public void drive() { Console.WriteLine(Audi实现的drive方法); } } internal class Program { static void Main(string[] args) { ICar car1 new Benz(); car1.drive(); ICar car2 new Bmw(); car2.drive(); ICar car3 new Audi(); car3.drive(); Console.ReadKey(); } }七、类型转换1.介绍使用多态时只能调用子类|实现类中继承、重写|实现的父类|接口的方法。不能调用子类|实现类中独有的方法。转换类型后就可以调用子类独有的方法了。2.转换1. 使用多态创建对象父类型|接口类型 对象名1 new 子类型|实现类型();Person person new Zs();2. 类型转型1. 方式1子类型|实现类型 对象名2 (子类型|实现类)对象名1;Zs zs1 (Zs)person;2. 方式2子类型|实现类型 对象名3 对象名1 as 子类型|实现类型;as关键字 用于将一个对象强制转换为指定的类型。Zs zs2 person as Zs;3.as 和 is 区别is操作符主要用于检查一个表达式的类型是否与指定的类型兼容而as操作符主要用于将一个对象强制转换为指定的类型。

更多文章