C#面向对象随笔整理: inherit, abstract,virtual override

1. 面向对象特点:封装,多态,继承
1.1 类成员:字段,属性,方法,索引,构造函数等.
1.2 实例类的成员可以是静态成员或实例成员,但静态类的成员必须都是静态的,所以实例类可以含有静态构造函数,
1.3 静态类的成员都是静态的,静态成员在程序运行过程中会一直占用内存,直到程序运行结束为止,二实例化类本身不占内存,实例化后的对象才建立引用关系占堆内存.
1.4 创建类的对象后,需要给对象的每个属性进行赋值,这个过程称之为对象的初始化,对象初始化有两种方法:
1.4.1 实例化对象后,直接对对象属性进行赋值:对象.属性名=属性值;
1.4.2 实例化对象时,对象后面直接加花括号,在花括号内对属性赋值,完成对象的初始化(类初始化器)
1.5 属性:可以在set和get访问器代码中,对字段提供保护,可以在赋值时对赋值进行限制,也可以在取值时对字段值进行限制
    string _name;
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;    
        }
    }
    通过给属性赋值,达到限制赋值范围,最终将value赋值给字段.
    获取属性值,是通过get访问器,获取字段的值,这个过程也可以对可取的字段值范围进行限制
    对于私有字段,其属性就是中间商,对字段进行限制
    属性的本质是方法,而不是数据成员

    自动属性:(定义好字段后,可以用快捷键Ctrl + r + e,回车,生成自动属性代码)
    public string Name{get;set;}

    自动属性初始化属性值
    public string Name{get;set;} = "David";
    public string Name=>"David";
1.6 针对只读属性,可以通过构造函数对该属性的私有字段进行赋值,然后通过属性获取.
1.7 抽象类定义了抽象方法M,如果A类的子类B也是抽象类,不需要实现A类的抽象成员M,如果B类的子类不是抽象类,则必须实现A类的抽象成员M.

2.this关键字的作用:1.代表当前类的对象,2.调用当前类的全参构造函数

3.也可以在子类的构造函数中用base,指定调用的父类构造函数

4.继承作用:解决了代码冗余,方便项目功能拓展,为多态提供支持

5.类继承特性:单根性和传递性,即派生类只能有一个基类,但基类可以有N多派生类,可以派生N代,,,

6.创建子类对象时,会默认调用父类的无参构造函数,再调用自己的构造函数,所以子类对象new完成后,能看到父类的公共成员

7.里氏转换: 1.子类对象可以赋值给父类对象; 2.父类对象装的是某个子类,则可以强转成该子类对象;

Person p = new Student();

p对象只能调用Person类的公共成员,无法调用Student()成员;可以将p强转成Student()对象(Student s = (Student)p;),才能调到Student()成员

is/as关键字:
if(p is Student)
{
   //转换成功
}

Student tmp = p as Student;//转换不成功tmp = null,转换成功则p为Student对象

8.多态实现方式:虚方法virtual; 抽象类abstract,接口

如果子类和父类含有相同的方法,那么子类定义用new关键字可以把父类的方法会被隐藏掉调用,即子类无法再调用父类该方法

多态是面向对象最高级境界 将面向对象发挥到极致    让一个父类对象能够表现出多种子类的状态
父类子类有相同方法,。。。。用多态,从父类的对象指向哪个子类对象,很可以调到哪个子类的成员.
实现多态方式   虚方法     抽象类     接口
8.1.虚方法
步骤
(1.)   将父类的方法标明为虚方法,  方法关键字virtual,有具体的方法体实现代码
(2.)   子类可以将这个父类同名方法重写一次,方法关键字override
给父类对象赋值的是其子类对象时,调用的方法依然是父类的方法(继承的用法也体现出这一点),不过侦测到父类成员的关键字virtual后,即转向子类的override同名函数执行代码,从              而实现用虚方法来实现对子类方法的调用,实现多态的效果.
 如果给父类对象赋值的是父类自己类的对象,则调用自己的virtual方法

但是要注意,子类对象(Son son = new Son())son对象调不到父类的虚方法,因为父类的虚方法已经被自己重写了,所以子类对象只能调到自己override的方法,这点要注意!!!
 8.2.抽象类 关键字abstract 抽象类不能实例化自己的对象
(1.)抽象类的抽象成员没有实际的实现方式,所有的abstract成员都必须在子类中重写(除非子类也是抽象类),且重写方法的签名必须和父类的抽象方法一致
(2.)子类重写成员可以手动写,也可以写完父类定义抽象成员后,在写子类继承关系时,按Alt+Shift+F10,选择“实现抽象类...”,即可自动重写父类的抽象成员
(3.)抽象类中可以有静态成员,也可以有实例成员,虽然抽象类不能实例化自己对象,但其子类可以通过继承来使用这些成员,这一点很有用!
同理,抽象类也可以有自己的构造函数,子类构造函数通过base关键字来调用
(4.)抽象成员必须在抽象类中

(5.)抽象类多态实现方式:给抽象父类对象赋值的是其子类对象时,调用的方法依然是抽象父类的方法(继承的用法也体现出这一点),不过侦测到父类成员的关键字abstrace后,即转向子类的override同名函数执行代码,从而实现用抽象类抽象成员的重写方式来实现抽象类多态的效果.

父类中的方法不知道如何实现的时候或者不需要具体实现的时候,可以考虑将父类写成抽象类,方法写成抽象方法,将具体的实现方式用子类的重写方法  
抽象类和接口无法创建对象  
抽象方法没有方法体,即没有大括号,有大括号,即使是空代码,也是有方法体!!!抽象方法存在的意义就是为了让子类重写
子类中实现同名方法的重写,关键字:override
用抽象类虚方法实现以下多态 :狗狗会叫  猫咪会叫
思路:
1.猫狗的叫是平行关系,所以要建一个抽象的父类Animal,
2.让子类重写animal的方法,实现用父类对象(装的是猫或狗子类),根据给Anmial赋值的对象,调用对应的该子类重写方法
3.实例化父类对象指向子类
Animal a = new Animal(); //抽象类不能被实例化,但可以实例化为装子类的对象,如下一行代码   
 Animal[] animal = new Animal[]{new Cat(),new Dog()};    //new 子类对象赋值给父类对象,new的类名后面加的(),代表实例化调用的是无参构造函数
foreach (Animal item in animal)
{
    item.Bark();
}
Console.ReadKey()           

8.3 接口实现多态:            //接口也是实现多态的一种方式

接口(Interface)是一种引用类型,它定义了一个规范,包括方法、属性、事件、索引器,但不包含实现。接口不能直接实例化,它的目的是为了实现多态性和代码的松耦合。(啥是松耦合??)

接口成员只包含方法、自动属性(自动属性虽然有get set,但是没有对应的{}方法体实现),不能有字段、普通属性;

自动属性,普通属性区别
自动属性虽然没有对私有字段进行赋值或获取操作,但是,编译的时候C#会根据属性的类型,自动生成字段,其作用和普通字段相同

接口成员方法没有方法体,不予许有访问修饰符,接口成员修饰符默认就是public
接口定义的成员必须在子类中全部实现

如果给接口I赋值的是C类对象,且C:I,那么I对象可以调用C类实现接口的成员

接口实现多态,及显式,隐式实现接口成员的demo见另一篇帖子,如下链接:

显式隐式实现接口-CSDN博客

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值