十三、类的继承、访问级别

类的继承与访问控制

在这里插入图片描述

类的继承

  • 使用sealed修饰的类,是私有类,不能作为基类使用
  • C#中一个类,只能有一个父类,但是可以实现多个接口
  • 子类的访问级别不能超过父类的访问级别
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace HelloOOP {internal class Program {static void Main(string[] args) {//从代码上验证继承关系Type t = typeof(Car);Type tb = t.BaseType;Type ttTop = tb.BaseType;Console.WriteLine(ttTop.FullName);/* 所有的类都继承自Object* 并且Object上面就没有父类了,Object是处于最顶端的*/Console.WriteLine(ttTop.BaseType == null);/* 是一个 is a, 一个子类的实例也是父类的实例* 一个学生一定是一个人* 一个父类的实例不一定是子类的实例* 一个人不一定是一个学生*/Car car = new Car();Console.WriteLine(car is Vehicle);}}class Vehicle { }//Car类继承自Vehicle类class Car : Vehicle { }// 1.私有类,不能当做基类来使用sealed class Bycicle { }
}

成员的继承与访问

继承

继承的本质:派生类在基类已有的成员的基础之上,对基类进行的横向和纵向上的扩展

  • 当继承发生的时候,子类对父类所有的成员是全盘继承的,除了三种东西不会被继承

    • 静态构造器:用于初始化类的静态数据。
    • 实例构造器:在创建类的新实例时调用。 每个类都必须定义自己的构造函数。
    • 析构函数(终结器):由运行时的垃圾回收器调用,用于销毁类实例。
  • 在派生的过程当中,我们进行的是扩展

    也就是不能对父类的成员进行去除,只能扩展,这是静态类型语言(c++、c#、Java)的特点

    而某些动态语言(python、JavaScript)则可以去除父类的成员

  • 横向扩展即,类成员的增加;纵向扩展即,类成员的重写

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace HellloAccess {internal class Program {static void Main(string[] args) {Car car = new Car();Console.WriteLine(car.Owner);}}class Vehicle {public Vehicle(){this.Owner = "N/A";}public string Owner { get; set; }}class Car : Vehicle { public Car() {//this.Owner = "Car Owner";}public void ShowOwner() {//只能访问上一级的对象Console.WriteLine(base.Owner);/* 创建子类对象的时候,是从基类的构造器开始* 一层一层往下构造的,最终构造出来子类的对象*/Console.WriteLine(this.Owner);/* 当前这个base.Owner和this.Owner在这个例子中* 都指向的是同一个字符串即"Car Owner"* 因为子类中的构造器把原来的Owner覆盖了*/}}
}

实例构造器无法被继承

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace HellloAccess {internal class Program {static void Main(string[] args) {Car car = new Car("Ygc");Console.WriteLine(car.Owner);/* 实例构造器无法被继承* 但是会先调用父类的实例构造器,然后再调用子类的实例构造器*/}}class Vehicle {public Vehicle(string owner){this.Owner = owner;}public string Owner { get; set; }}class Car : Vehicle {/* 当父类的构造器,是带参数的。* 那么父类的默认的构造器就会被覆盖掉* 那么此时调用子类的默认构造器是不行的* 因为调用子类的默认构造器,会先调用父类的默认构造器* 而此时,父类的默认构造器是不存在的,会发生冲突*///更改的办法:public Car() : base("N/A") {//this.Owner = "Car Owner";}//或者写一个带参数的构造器public Car(string owner) : base(owner){}public void ShowOwner() {Console.WriteLine(this.Owner);}}
}

继承中的访问级别

派生类和派生记录不能具有高于其基类型的可访问性。

虽然基类的其他所有成员都可供派生类继承,但这些成员是否可见取决于它们的可访问性。 成员的可访问性决定了其是否在派生类中可见。

类成员的访问级别是以类的访问级别作为上限的。

internal class Student{public string name;//所以这个类成员是不能被其他程序集所访问的
}

父类中的私有字段被限制在了父类的类体中,子类是不能直接访问的,但是是继承了的

以下代码可以证明:


namespace MyLib
{public class Vehicle{private int _rpm;//命名前面加_表示,这是一个私有字段public void Accelerate() {_rpm += 1000;}//该属性返回的是私有字段/ 100之后的值public int Speed {  get { return _rpm / 100; } }}public class Car : Vehicle{  }
}using System;
using MyLib;namespace HellloAccess {internal class Program {static void Main(string[] args) {Car car = new Car();car.Accelerate();car.Accelerate();Console.WriteLine(car.Speed);/* 使用car对象调用父类的属性,能够成功返回* 说明,父类的私有字段实际上也是被子类所继承的,* 只是不能被car类所访问*/}}
}

类成员的访问级别:

  • 只有在基类中嵌套的派生类中,私有成员才可见。 否则,此类成员在派生类中不可见。

    private会把访问级别限制在类的类体中,所以只有嵌套的派生类才能访问

    public class A
    {private int _value = 10;public class B : A{public int GetValue(){return _value;}}
    }public class C : A
    {//    public int GetValue()//    {//        return _value;//    }
    }public class AccessExample
    {public static void Main(string[] args){var b = new A.B();Console.WriteLine(b.GetValue());}
    }
    // The example displays the following output:
    //       10
    
  • 受保护成员仅在派生类中可见。

    会把访问级别限制在继承链上,并且可以夸程序集

    protected更多的用在方法上

    namespace MyLib
    {public class Vehicle{protected int _rpm;private int _fuel;//表示油量//加油的方法public void Refuel() {_fuel = 100;}/* 烧油方法* 即不想暴露给外界,引发错误的调用* 又想继承给子类继续调用* 于是就用,protected访问修饰符*/protected void Burn(int fuel) {_fuel -= fuel;}public void Accelerate() {Burn(1);//普通加速耗油1_rpm += 1000;}public int Speed {  get { return _rpm / 100; } }}public class Car : Vehicle{  public void TurboAccelerate() {//烧两次油,加速3000Burn(2);//涡轮增压加速,耗油2_rpm += 3000;}}
    }using System;
    using MyLib;namespace HellloAccess {internal class Program {static void Main(string[] args) {Car car = new Car();car.Refuel();//先加油car.TurboAccelerate();//再加速Console.WriteLine(car.Speed);Bus bus = new Bus();bus.Refuel();bus.SlowAccelerate();Console.WriteLine(bus.Speed);Console.ReadKey();}}class Bus: Vehicle {public void SlowAccelerate() {//夸程序集,仍然可以调用父类的protected的成员Burn(1);_rpm += 500;}}
    }
  • 内部成员仅在与基类同属一个程序集的派生类中可见, 在与基类属于不同程序集的派生类中不可见。

  • 公共成员在派生类中可见,并且属于派生类的公共接口。 可以调用继承的公共成员,就像它们是在派生类中定义一样。

    public class A
    {public void Method1(){// Method implementation.}
    }public class B : A
    { }public class Example
    {public static void Main(){B b = new ();b.Method1();}
    }
    

访问修饰符(全)

这一段是我抄的微软官方文档

  • public:同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员。 某一类型的公共成员的可访问性水平由该类型本身的可访问性级别控制。
  • private:只有同一 classstruct 中的代码可以访问该类型或成员。
  • protected:只有同一 class 或者从该 class 派生的 class 中的代码可以访问该类型或成员。
  • internal:同一程序集中的任何代码都可以访问该类型或成员,但其他程序集中的代码不可以。 换句话说,internal 类型或成员可以从属于同一编译的代码中访问。
  • protected internal:该类型或成员可由对其进行声明的程序集或另一程序集中的派生 class 中的任何代码访问。
  • private protected:该类型或成员可以通过从 class 派生的类型访问,这些类型在其包含程序集中进行声明。

在这里插入图片描述

各种东西的默认访问级别

默认情况下,类成员和结构成员(包括嵌套的类和结构)的访问级别为 private。 不能从包含该类型的外部访问私有嵌套类型。

在这里插入图片描述

面对对象的实现风格

面向对象语言学习方法的问题

不要因为学了某个语言,就极大的夸赞该语言的优点,而藐视其他语言的缺点。

C#中的派生和继承,仅仅只是众多语言派生和继承的一种风格,还有其他的派生和继承的风格。

**C#使用的是Class-based风格,基于类的封装、继承和多态。**目前是主流,C++,C#,Java。

JavaScript使用的是Prototype-based风格,基于原型的封装、继承和多态的方式

Java不是单根的类型系统,它的引用类型是单根的,但是它还有一套系统,叫基本类型系统。


有部分内容,我是抄的微软的官方文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/512384.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】【洛谷】P1125笨小猴

一、个人解答 #include<stdio.h> #include<string.h>int prime(int num);int main() {char max a, min z;int maxn0, minn1000;char str[100];int num[26] { 0 };fgets(str, sizeof(str), stdin);str[strcspn(str, "\n")] \0;for (int i 0; str[i]…

CentOS的yum报错except OSError, e:

报错信息 Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile base: mirrors.cloud.aliyuncs.comextras: mirrors.cloud.aliyuncs.comupdates: mirrors.cloud.aliyuncs.com File “/usr/libexec/urlgrabber-ext-down”, line 28 except OSError, e: ^…

Gradle学习(一)

最近在学习Gradle&#xff0c;感觉有些东西没见过&#xff0c;记录一下&#xff01; 1.Gradle与Maven的目录框架 2.Gradle的命令行安装 注&#xff1a;学习常用的是使用脚手架生成gradle项目 3.

maven项目报错Cannot resolve plugin org.apache.maven.plugins:maven-war-plugin:2.2

如果IDEA整合maven没有问题&#xff0c;还是报这个错误&#xff0c;很大可能是由于在下载过程中存在网络问题&#xff0c;导致文件下载一半而停止&#xff0c;但是已经在仓库中存在这个文件夹&#xff0c;解决方法是删除文件夹重新下载即可。 删除本地仓库下的\org\apache\mav…

AI大预言模型——ChatGPT与AI绘图及论文高效写作

原文链接&#xff1a;AI大预言模型——ChatGPT与AI绘图及论文高效写作 2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网…

灯丝灯双通道低过温高压线性恒流芯片SM2082ED的应用及特性解析

双通道低过温高压线性恒流芯片是一种电子芯片&#xff0c;它具有双通道设计&#xff0c;可以在高电压条件下工作&#xff0c;并具有低过温特性。这种芯片通常用于需要高电流和高电压的应用&#xff0c;如LED照明、激光器、电机驱动等。 双通道设计意味着该芯片可以同时处理两个…

分布式测试插件 pytest-xdist 使用详解

使用背景&#xff1a; 大型测试套件&#xff1a;当你的测试套件非常庞大&#xff0c;包含了大量的测试用例时&#xff0c;pytest-xdist可以通过并行执行来加速整体的测试过程。它利用多个进程或计算机的计算资源&#xff0c;可以显著减少测试执行的时间。高计算资源需求&#…

保姆级GeoWebCache矢量瓦片切片流程

1矢量切片解决方案 1.1Geoserver配置geowebcache插件 参考文章 (53条消息) 独立安装geoservergeowebcache发布arcgis切片服务_itouch_ok的专栏-CSDN博客 1.将下载好的geoserver 2.19.3安装部署 将下载好的geowebcache 2.19.3的war包解压到 GeoServer 安装目录下./usr/loc…

生活干货知识:手机流量卡网速不佳的常见原因及解决办法

最近有很多的小伙伴后台留言给我&#xff0c;为什么有时候手机网路那么差呢&#xff1f;甚至连一个基本的网页都打不开&#xff0c;播放视频和电影更不用说了&#xff0c;这样严重影响了我们的使用体验&#xff0c;到底什么原因导致的呢&#xff1f;相信很多小伙伴至今仍然未清…

文件恢复软件推荐,数据恢复,很简单!

“我有一些很重要的文件被误删了&#xff0c;尝试了各种方法都无法找回&#xff0c;听说借助文件恢复软件或许有机会找回重要的数据&#xff0c;大家有什么比较好用的文件恢复软件推荐吗&#xff1f;” 在数字化时代&#xff0c;电脑和各种存储设备对我们来说都是比较重要的&am…

安装MySQL

一、下载安装包 官网下载地址 二、下载完成打开程序自定义安装 1. 2. 3. 下一步 下一步 4. 5. 6. 输入密码123456 安装成功

SuperPoint和SuperGlue 的算法介绍及学习应用经验分享

SuperPoint和SuperGlue 的算法介绍及学习应用经验分享 2024年01月03日 10:38186浏览 3喜欢 0评论 视频地址&#xff1a; SuperPoint和SuperGlue 的算法介绍及学习应用经验分享 好想 特征点匹配&#xff0c;为了计算位姿 特征点&#xff1a;关键点描述子&#xff08…