封装,继承,多态(C#)

封装:将对象们的共同属性行为封装起来,载体为类。

就是:现实生活中的实例对象,找出他们的共同部分,用属性加行为归纳一下。类描述好后,就可new出具体的对象了。

类:字段,属性,构造方法,自定义方法 组成

 public:对任何类和成员都公开,无限制访问
private:仅对该类公开
protected:对该类和其派生类公开
internal:只能在本项目中访问该类

继承:拿来主义,减少重复的工作。

就是:汽车有发动机,把发动机继承给汽车。这样汽车在设计的时候就不需要再去重复设计发动机了。当然也可以覆盖发动机(子类的方法签名要和父类一样,但访问权限需要大于父类,另加new修饰。称为重构)除了覆盖,还有虚方法:比如虚方法的发动机,子类可以直接用,也可以override重新设计发动机。

new:在子类方法中出现,用于顶替掉父类中相同名字的方法。这2个方法是同时存在的,需要用到父类方法的时候,方法前面加 【  base.  】调用子类的方法时可以在前面加【  this. 

override: 只会出现在子类内,作用是,父类只声明,没有方法体,子类去实例化具体的方法体。

public class father
    {
        public string name = "我是你爹!";
        public int age = 66;

        public string toyoungtosimple()
        {
            string str = "爸爸的爸爸叫什么?";
            return str;
        }

    }
public class son :father
    {
//重构只能new不能override
        public new string name = "我是你儿子!";
        public new int age = 16;

        public new string toyoungtosimple()
        {
            string str = "叫奶奶?";
            return str;
        }

        public  string speak老爸说的啥()
        {
           return  base.toyoungtosimple()+base.name+base.age;
        }

    }

 另加 new 修饰 才能重构父类    覆盖 

interface 声明接口:方法纯声明,没有方法体

  interface  father
    {
        //public string Name { get; set; }// 不能用 public 修饰
        string name { get; set; }
         int age { get; }
        string toyoungtosimple();     //只能声明,不能有方法体
        //{
        //    //string str = "接口方法";
        //    //return str;
        //}
    }
   public class son : father  // 点击灯泡:实现接口
    {
        string Name;
        int Age;
        public string name { get => Name ; set => Name=value; }

        public int age { get => Age; set => Age = value; }

        public string toyoungtosimple()
        {
            return $"实现接口。儿子今年{this.age}岁。";
        }
    }

abstract 声明抽象类,部分方法有方法体

 father的等级是private,子类就不能是public

 abstract class  father
    {
        public string Name { get; set; }// 公有
        string name { get; set; }//  私有  子类不能继承
        int age { get; }
      public  abstract  string toyoungtosimple();//只能声明,不能有方法体,必须是public
        //{
        //    //string str = "抽象方法";
        //    //return str;
        //}

        public string father说()
        {
            //return "下雨收衣服啊!";
            return toyoungtosimple();
        }
class son : father // 父类私有,所以不能 public
  {

    int age;
    public string name { get => base.Name ; set => base.Name=value; }//显示的说明父类中属性

    public int Age { get => age; set => age = value; }// 父类中私有,不能继承,只能子类中造

        //public string toyoungtosimple()
        //{
        //    return $"实现接口。儿子今年{this.age}岁。";
        //}

    public override string toyoungtosimple()
        {
            return "下雨收衣服啊!";
        }
  }

 

 提示:儿子改写了父亲的方法。  父亲变量可以用儿子们做右值,实现同方法名,不同方法体。

sealed 类声明时可防止其他类继承此类,在方法中声明则可防止派生类重写此方法。

  sealed class  father
    {

 重写,接口,抽象方法,虚方法,封闭sealed就像医院的 主药和 副药,用于围堵漏洞。

常用关键字

virtual 表示虚方法可以被派生类重写

override 表示重写父类的方法

base 表示父类对象

多态:依赖于抽象类接口

就是,父类中某个方法功能还没决定好,让子类去实现。(子类做父类的右值,子类去覆盖掉父类的方法体)例如:我生产了一个汽车框架,把这个框架给一群供货商去派生。供货商去完善包围,发动机,钣金,车灯等。供货商给我的都是派生的子类,我只需要 new List<汽车框架>来处理,就能使用子类给父类的功能。

第一代手机,只留了充电口,没有数据线和充电器。派生的第n代手机有数据线和充电器。这样可以给老祖宗充电。导入的电影,也由后代决定。用第一代手机可以看后代的电影。

多态的流程是倒过来用的。父类定义功能,子类去实现功能方法体,子类做父类的参数传递,List<父类>就能管理不同的子类。

 就像List<发动机>  子类就是汽车。 汽车做参数传给父类,拆出发动机,可以给另一辆汽车用。

抽象类:抽象有抽象类和抽象方法,

只要类中有一个抽象方法,此类就标记为抽象类。

子类的方法体给父类(父类只声明方法)(子类完善方法体)

抽象方法只有声明,没有方法体。子类必须写出方法体。这个是倒过来用的,子类的方法体给父类用。new 父类 动态数组,每个下标父类的抽象方法对应不同的实例子类方法。

接口类:接口的所有方法都没有方法体。子类必须实例化接口的每位成员。

虚方法:虚方法是默认方法,子类可以选择是否覆盖父类的虚方法。

 class father
    {
        public string Name { get; set; }// 公有
        string name { get; set; }//  私有  子类不能继承
        int age { get; }
        public virtual string toyoungtosimple()  //吾乃虚方法
        {
            string str = "老师虚的掉头发。。。";
            return str;
        }

        public string father说()
        {
            //return "下雨收衣服啊!";
            return toyoungtosimple();
        }
    }

补充【隐藏方法(重要!)】:

隐藏方法:在派生类中定义的和基类中的某个方法同名的方法,使用 new 关键字定义。

如在基类 Animal 中有一方法 Sleep():

public void Sleep()
{
    Console.WriteLine("Animal Sleep");
}

则在派生类 Cat 中定义隐藏方法的代码为:

new public void Sleep()
{
    Console.WriteLine("Cat Sleep");
}

或者为:

public new void Sleep()
{
    Console.WriteLine("Cat Sleep");
} 

注意:隐藏方法不但可以隐藏基类中的虚方法,而且也可以隐藏基类中的非虚方法。

虚方法和隐藏方法的调用:【容易混淆!!!】
虚方法的调用:调用上,使用子类构造的对象调用虚方法,就会调用子类的方法,使用父类构造的对象(父类构造的实例),就会调用父类的方法。【注意这里是 父类构造的实例=>调用父类的方法】

隐藏方法的调用:调用上, 使用子类类型的声明调用隐藏方法,就会调用到子类的方法。若想调用被隐藏的方法(父类的方法),需要用父类类型的声明来调用。【注意这里是 父类类型的声明=>调用父类的方法】

具体理解,见下边实例:
————————————————
版权声明:本文为CSDN博主「明如正午」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_40003796/article/details/125273933

using System;
namespace ConsoleApp1
{
    class Enemy
    {
        public void Move()
        {
            Console.WriteLine("调用了Enemy的Move方法");
        }
        public virtual void Attack()
        {
            Console.WriteLine("Enemy Attack");
        }
    }


    class Boss : Enemy
    {
        public override void Attack()
        {
            Console.WriteLine("Boss Attack");
        }

        public new void Move()
        {
            Console.WriteLine("Boss Move");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            #region 隐藏方法的调用
            Boss oneEnemy = new Boss();
            oneEnemy.Move(); // 调用的隐藏方法,用子类的声明来调用的,调用的就是子类的Move。

            //【下边两种结果一样,主要看声明的是什么类】
            // 【重点理解!!!】调用的隐藏方法,用父类的声明来调用的,调用的就是父类(Enemy)的Move方法。
            Enemy twoEnemy = new Boss(); 
            twoEnemy.Move();

					// 调用的隐藏方法,用父类的声明来调用的,调用的就是父类(Enemy)的Move方法。
            Enemy thirdEnemy = new Enemy();
            thirdEnemy.Move();
            #endregion 隐藏方法的调用

  				 Console.WriteLine();
  				 
            #region 虚方法的调用
            //用什么类型 来构造,在调用方法的时候就会调用什么类型的方法。

					 // 调用虚方法,用父类来实例化的,所以调用的是父类的Attack方法。
            Enemy threeEnemy = new Enemy();
            threeEnemy.Attack(); 
 	
 			      //【重点理解!!!】 调用虚方法,用子类来实例化的,所以调用的就是子类(Boss)的Attack方法。
            Enemy fourEnemy = new Boss();
            fourEnemy.Attack(); 
            #endregion 虚方法的调用         

            Console.ReadKey();
        }
    }
}

运行结果:

Boss Move
调用了Enemy的Move方法
调用了Enemy的Move方法

Enemy Attack
Boss Attack

我的总结:

多态里:
        接口:儿子A的接口功能,裁剪出【接口】,给儿子B,这样儿子B也获得A的接口功能,
             最主要的好处是:接口漏写字段,属性,方法,编译器都会报错。【必须实现接口的每位成员】
             使用方向是:父亲》儿子A》儿子B
       
        抽象:父亲借用儿子们的能力。父亲没能力买车,但是儿子有能力买车,把儿子裁剪后给父亲,这样父亲就有能力买车了。
             使用方向是:儿子》父亲

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值