• C#之面向对象


    面向对象

    面向对象三大特征:封装、继承、多态

    封装:类对外部提供public方法,调用者不用关心类内部的运行机制

    继承:子类继承自父类,子类可以继承父类所有非private成员,实现代码重用;

    多态:子类中可以覆盖(override)父类中的virtual方法;父类类型的变量可以指向子类类型的对象,调用的方法如果子类override了,则调用的是子类的实现(一个方法在不同环境下不同的表现形态)。

    一、封装

    1.封装的具体表现

    (1)属性封装字段

    public class Person
        {
            private int _id = -1;
    
            public int Id
            {
                get
                {
                    return _id;
                }
                set
                {
                    _id = value;
                }
            }
        }

    对内部使用的字段是_id,外部使用的是Id属性。对属性名称进行修改,不需要修改_id名称。

    (2)方法的多个参数封装成一个对象

    (3)将一堆代码封装到一个方法中

    (4)将一些功能封装到一个类中

    (5)将一些具有相同功能的代码封装到一个程序集中(dll、exe),并且对外提供统一的访问接口(方法名、属性名等)

    二、继承(类与类之间的关系):一个类继承另一个类,那么这个类也就有了另一个类的非private成员

    1.判断一个继承是否合理?(子类 is a 父类)

    比如:香蕉是水果吗?是。香蕉类继承水果类

    2.继承的好处

    (1)代码重用

    (2)多态

    里氏替换原则:需要一个父类类型时,给一个子类对象是可以的。

    里氏替换原则就是为了多态=>多态就是为了增加程序的可扩展性,灵活性。

    public class Person
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    
        public class Student:Person
        {
            public string StuId { get; set; }
        }
    
    调用部分:
    Person p1 = new Student();

    因为有了继承,便有了里氏替换原则,有了里氏替换原则,便有了多态

     3.继承中的构造函数问题

    public class Person
        {
            public Person(int id,string name)
            {
                this.Id = id;
                this.Name = name;
            }
            public int Id { get; set; }
            public string Name { get; set; }
        }
    
        public class Student:Person
        {
            public string StuId { get; set; }
    
            public Student(int id, string name, string stuid)
            {
                this.Id = id;
                this.Name = name;
                this.StuId = stuid;
            }
        }

     当一个子类继承父类以后,该子类中的所有构造函数默认情况下,在自己被调用之前都会先调用一次父类的无参构造函数,如果此时父类中没有无参的构造函数,则提示报错!

    解决方法一:在父类中添加一个无参构造函数

    解决方法二:在子类的构造函数后面通过:base()的方式,明确指定要调用父类中的那个构造函数。

    public class Person
        {
            public Person(int id,string name)
            {
                this.Id = id;
                this.Name = name;
            }
            public int Id { get; set; }
            public string Name { get; set; }
        }
    
        public class Student:Person
        {
            public string StuId { get; set; }
    
            public Student(int id, string name, string stuid):base(id,name)
            {
                this.StuId = stuid;
            }
        }

     :base()表示调用父类的构造函数

    三、多态

    1.多态的三种表现形态

      (1)虚方法

      (2)继承

      (3)接口

    2.多态实行开放封闭原则:对修改封闭,对扩展开放

    3.多态的作用:把不同的子类对象当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

    4.实现多态的三种方法的区别:

      (1)虚方法是实例类,具有默认实现

      (2)抽象方法没有默认实现,除非子类也是一个抽象类

      (3)接口存在是为了解决:

        1.类的多继承问题

        2.类继承以后体积庞大的问题

     四、接口

    接口是一种规范、协议。约定好遵守某种规范就可以写通用的代码了。

    接口存在的意义就是为了多态

    接口的存在解决了:

      (1)类的单继承问题

      (2)类继承以后体积庞大的问题

    1.接口里面只能包含方法:

      (1)方法

      (2)属性

      (3)索引器

      (4)事件

      因为属性,索引器,事件本质上都是方法。【字段不能定义在接口中】

    2.接口中的所有成员都不能显示的写任何访问修饰符,默认是public的访问修饰符

    3.方法,属性,索引器在接口中的定义方式

    public interface DefinitionInterface
        {
            /// <summary>
            /// 定义方法
            /// </summary>
            void SayHello();
    
            /// <summary>
            /// 定义返回值是string类型的方法
            /// </summary>
            /// <returns></returns>
            string Eat();
            /// <summary>
            /// 定义属性
            /// </summary>
            string Name
            {
                get;
                set;
            }
            /// <summary>
            /// 定义索引器
            /// </summary>
            /// <param name="index"></param>
            /// <returns></returns>
            string this[int index]
            {
                get;
                set;
            }
        }

    4.接口不能被实例化,就是为了让子类来实现的

    5.接口中的成员,子类必须实现

    五、虚方法与抽象方法

    1.虚方法

      (1)具有父子类关系

      (2)父类需要重写的方法添加virtual

      (3)子类重写的方法添加override

    class Program
        {
            static void Main(string[] args)
            {
                Person p1 = new Student();
                p1.SayHello();
                Console.ReadKey();
            }
        }
    
        public class Person
        {
            public string Name { get; set; }
            public virtual void SayHello()
            {
                Console.WriteLine("人类说Hello");
            }
        }
    
        public class Student:Person
        {
            public override void SayHello()
            {
                Console.WriteLine("学生说Hello");
            }
        }

    Student类重写了子类的SayHello方法,那么在调用p1.SayHello();方法时就会调用重写的方法

    2.抽象方法

      (1)抽象类中可以有实例成员,也可以有抽象成员

      (2)抽象成员必须包含在抽象类中

      (3)抽象成员不能有任何实现

      (4)抽象类不能用来实例化对象,只能被继承

      (5)抽象成员子类继承以后必须重写override,除非子类也是一个抽象类

    public abstract class Person
        {
            public string Name { get; set; }
    
            public abstract void SayHello();
            
        }
    
        public class Student:Person
        {
            public override void SayHello()
            {
                Console.WriteLine("Student类重写Person类");
            }
        }

    虚方法和抽象方法的区别:

      (1)虚方法有默认实现,抽象方法没有默认实现。

      (2)如果虚方法不重写,那么就调用父类的方法;抽象方法中子类必须实现抽象方法,除非子类也是一个抽象方法。

    六、静态类

    1.静态类的特点

      (1)静态类中只能有静态成员。

      (2)静态成员不是必须写在静态类中。

      (3)在程序中的任何一个地方访问该静态成员,其实都访问的是同一块内存。

      (4)静态成员的数据直到程序退出以后才释放资源;实例对象只要使用完毕就可以执行垃圾回收了。

    2.静态类和静态成员要使用static修饰

    3.静态构造函数

      (1)类中的静态成员,在第一次使用静态成员的时候进行初始化

      (2)静态构造函数不能手动来调用,而是在第一次使用静态

    七、访问修饰符

    1.访问修饰符

      (1)private 只能在当前类的内部可以访问

      (2)protected 只能在当前类内部以及所有子类的内部可以访问

      (3)internal 在当前程序集内部访问

      (4)public 任何地方都可以访问

    2.命名空间中的访问修饰符只能是public或internal,不能是其他访问修饰符(类不加访问修饰符默认是internal)

    3.类的成员变量,如果不写访问修饰符默认是private

    4.访问级别约束:

      (1)子类的访问级别不能比父类的高(会暴露父类的成员)

      (2)类中属性或字段的访问级别不能比所对应的类型访问级别高

      (3)方法的访问级别不能比方法的参数和返回值的访问级别高

  • 相关阅读:
    MVC @Html.TextBox 添加属性和样式
    当项目中出现“未能找到与此解决方案关联的源代码管理提供程序。项目将视为不受源代码管理”
    MVC视图中读取ViewBag传递过来的HashTable表数据
    使用NPOI导入导出标准的Excel
    网站文件下载代码
    C# 刷新页面浏览次数(点击量)+1
    sed
    Shell变量的取用、删除、取代与替换
    non-member function cannot have cv-qualifier
    awk学习
  • 原文地址:https://www.cnblogs.com/fengjiqiang123/p/11911835.html
Copyright © 2020-2023  润新知