首页 > 编程语言 >c#学习笔记-------------继承和抽象类

c#学习笔记-------------继承和抽象类

时间:2023-08-07 19:22:05浏览次数:45  
标签:c# Object System class 继承 ------------- 抽象类 public

类继承

通过继承我们可以定义一个新类,新类纳入一个已经声明的类并进行扩展

继承是面向对象的编程的一种基本特性。 借助继承,能够定义可重用(继承)、扩展或修改父类行为的子类。

成员被继承的类称为基类

继承基类成员的类称为派生类

C# 和 .NET 只支持单一继承。 也就是说,类只能继承自一个类。

不过,继承是可传递的。

这样一来,就可以为一组类型定义继承层次结构。

换言之,类型 D 可继承自类型 C,其中类型 C 继承自类型 B,类型 B 又继承自基类类型 A

由于继承是可传递的,因此类型 D 继承了类型 A 的成员。

并非所有基类成员都可供派生类继承。 以下成员无法继承:

  • 静态构造函数:用于初始化类的静态数据。

  • 实例构造函数:在创建类的新实例时调用。 每个类都必须定义自己的构造函数。

  • 终结器:由运行时的垃圾回收器调用,用于销毁类实例。

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

 

 保护级别

namespace Classes;
 
//只有在基类中嵌套的派生类中,私有成员才可见
public class A
{
    private int _value = 10;
    
    public class B : A
    {
        public int GetValue()
        {
            Console.WriteLine("--------B--------");
            return _value;           
        }
    }
}
 
public class C : A
{
    public int GetValue()
    {
//在这里会报错Compiler Error CS0122,
// CS0122:“"A._value" 不可访问,因为它具有一定的保护级别
        return _value;
    }
}

 

受保护成员仅在派生类中可见

namespace Classes;
 
//只有在基类中嵌套的派生类中,私有成员才可见
public class A
{
    protected int _value = 10;
    
    public class B : A
    {
        public int GetValue()
        {
            Console.WriteLine("--------B--------");
            return _value;           
        }
    }
}
 
public class C : A
{
    public int GetValue()
    {
        Console.WriteLine("--------C--------");
        return _value;
    }
}
 
public class AccessExample
{
    public static void Main(string[] args)
    {
        //A.B 是派生自 A 的嵌套类,而 C 则派生自 A。 私有 A._value 字段在 A.B 中可见。
        var b = new A.B();
        Console.WriteLine(b.GetValue());
 
        var c = new C();
        Console.WriteLine(c.GetValue());
    }
}
// The example displays the following output:
//--------B--------
//10
//--------C--------
//10

公共成员在派生类中可见,并且属于派生类的公共接口。

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   访问不受到限制
  • Protected       允许本类以及派生类进行访问
  • Internal        访问仅限于当前程序集
  • Protected Internal       允许本类或派生类访问,注意比Internal的范围广
  • Private           仅允许当前类访问,派生类不能访问

隐式继承

.NET 类型系统中的所有类型除了可以通过单一继承进行继承之外,还可以隐式继承自 Object 或其派生的类型。 Object 的常用功能可用于任何类型。

为了说明隐式继承的具体含义,让我们来定义一个新类 SimpleClass,这只是一个空类定义:

然后可以使用反射(便于检查类型的元数据,从而获取此类型的相关信息),获取 SimpleClass 类型的成员列表。 尽管没有在 SimpleClass 类中定义任何成员,但示例输出表明它实际上有九个成员。 这些成员的其中之一是由 C# 编译器自动为 SimpleClass 类型提供的无参数(或默认)构造函数。 剩余八个是 Object(.NET 类型系统中的所有类和接口最终隐式继承自的类型)的成员。

namespace Classes
{
    public class SimpleClass
    { }
}
namespace Classes;
 
using System.Reflection;
 
public class SimpleClassExample
{
    public static void Main()
    {
        Type t = typeof(SimpleClass);
        BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
                             BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
        MemberInfo[] members = t.GetMembers(flags);
        Console.WriteLine($"Type {t.Name} has {members.Length} members: ");
        //SimpleClass有九个成员:
        foreach (MemberInfo member in members)
        {
            string access = "";
            string stat = "";
            var method = member as MethodBase;
            if (method != null)
            {
                if (method.IsPublic)
                    access = " Public";
                else if (method.IsPrivate)
                    access = " Private";
                else if (method.IsFamily)
                    access = " Protected";
                else if (method.IsAssembly)
                    access = " Internal";
                else if (method.IsFamilyOrAssembly)
                    access = " Protected Internal ";
                if (method.IsStatic)
                    stat = " Static";
            }
            string output = $"{member.Name} ({member.MemberType}): {access}{stat}, Declared by {member.DeclaringType}";
            Console.WriteLine(output);
            //公共 GetType 方法:返回表示 SimpleClass 类型的 Type 对象。
            //GetType(Method):  Public, Declared by System.Object
 
            //受保护 MemberwiseClone 方法:创建当前对象的浅表复制。
            //MemberwiseClone(Method):  Protected, Declared by System.Object
 
            //受保护 Finalize 方法:用于在垃圾回收器回收对象的内存之前释放非托管资源。
            //Finalize(Method):  Protected, Declared by System.Object
 
            //公共 ToString 方法将 SimpleClass 对象转换为字符串表示形式,返回完全限定的类型名称。 在这种情况下,ToString 方法返回字符串“SimpleClass”。
            //ToString(Method):  Public, Declared by System.Object   
 
            //公共实例 Equals(Object) 方法、公共静态 Equals(Object, Object) 方法和公共静态 ReferenceEquals(Object, Object) 方法。 默认情况下,这三个方法测试的是引用相等性;也就是说,两个对象变量必须引用同一个对象,才算相等。
            //Equals(Method):  Public, Declared by System.Object
            //Equals(Method):  Public Static, Declared by System.Object
            //ReferenceEquals(Method):  Public Static, Declared by System.Object
 
            //公共GetHashCode 方法:计算允许在经哈希处理的集合中使用类型实例的值。
            //GetHashCode(Method):  Public, Declared by System.Object
            //.ctor(Constructor):  Public, Declared by Classes.SimpleClass
        }
    }
}

由于是隐式继承,因此可以调用 SimpleClass 对象中任何继承的成员,就像它实际上是 SimpleClass 类中定义的成员一样。

抽象类

abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用 abstract 修饰符以指示类只能是其他类的基类。

 

抽象类特性:

  • 抽象类不能实例化。

  • 抽象类可以包含抽象方法和抽象访问器。

  • 不能用 sealed 修饰符修改抽象类,这意味着该类不能被继承。

  • 从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。

在方法或属性声明中使用 abstract 修饰符以指示此方法或属性不包含实现。

 

抽象方法特性:

  • 抽象方法是隐式的 virtual 方法。

  • 只允许在抽象类中使用抽象方法声明。

  • 因为抽象方法声明不提供实实现,所以没有方法体;方法声明只是以一个分号结束,

 

抽象方法在签名后没有大括号 ({ })

例如:

  • public abstract void MyMethod(); 

  • 实现由 overriding 方法提供,它是非抽象类的成员。

  • 在抽象方法声明中使用 static 或 virtual 修饰符是错误的。

 

除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。

  • 在静态属性上使用 abstract 修饰符是错误的。

  • 在派生类中,通过包括使用 override 修饰符的属性声明可以重写抽象的继承属性。

抽象类必须为所有接口成员提供实现。

例子:

抽象基类

using System;
using System.Collections.Generic;
using System.Text;

namespace _09_抽象类
{
    public abstract class Enemy
    {
        private int hp;
        private int speed;

        public void Move()
        {
            Console.WriteLine("Move");
        }
        public abstract void Attack();

    }
}

子类继承需要实现其抽象方法

using System;
using System.Collections.Generic;
using System.Text;

namespace _09_抽象类
{
    public class Boss : Enemy
    {
        public override void Attack()
        {
            Console.WriteLine("Boss进行攻击");
        }
    }
}

 

   

标签:c#,Object,System,class,继承,-------------,抽象类,public
From: https://www.cnblogs.com/misakayoucn/p/17612504.html

相关文章

  • AtCoder Beginner Contest 313
    AtCoderBeginnerContest313-AtCoderA-ToBeSaikyo(atcoder.jp)从\(a_1\dotsa_{n-1}\)找出最大值与\(a_0\)比较即可#include<bits/stdc++.h>#defineintlonglong#defineendl'\n'usingnamespacestd;signedmain(){ios::sync_with_st......
  • more and more construction problem,what should i do ?
    一些构造CF1464FShowingOff显然原图连边会形成若干内向基环树森林,所有在同一个环上的点\(S\)是相同的,注意到原图是二分图,因此所有环都是偶环。一个重要观察是,我们可以让所有环的长度都是2,因为总可以把长度\(>2\)的环拆成若干个二元环,而且在\(S_{i,j}\geq2\)的限制......
  • vc++2008通过paho c语言客户端接入MQTT
    因项目需要,IoT平台需要支持vc++2008接入。因为Paho的c++客户端不支持低版本vc++,所以不得不尝试通过c语言的库实现。类库下载从github下载c语言包。例如:eclipse-paho-mqtt-c-win32-1.3.12.ziphttps://github.com/eclipse/paho.mqtt.c/releases类库整合和配置解压出来的c语言......
  • CSP模拟15
    CSP模拟15T1CF1850GTheMorningStar水题但是考场写挂了直接写阶乘会\(RE\)(这里\(A\)阶乘可以优化成两个数相乘)可以分解为4种不同斜率的直线用\(map\)存(点击查看代码#include<iostream>#include<cstdio>#include<map>#include<cstring>usingnamespacestd;#de......
  • v-model限制输入的妙用
    示例v-model.number即限制输入数字(原理是每次输入都会转化为数字,非数字则会丢弃)还有更多,如:v-model.trim:去除首尾空格。可以避免误输入一些不能看见的首尾空格。v-model.lazy:延迟更新。默认情况下,v-model在每次输入时都会立即触发input事件,而使用v-model.lazy可以将更新触发......
  • Java中抽象类和接口
    修饰符:抽象类中的抽象方法可以有public、protected和default这些修饰符,而接口中默认修饰符是public。不可以使用其它修饰符。一般来说,接口中不考虑Java8中default方法,没有实现的代码。抽象类可以定义抽象方法和非抽象方法。 接口和抽象类的职责不一样。接口主要用于制定规范。......
  • 从浅入深了解.NET Core MVC 2.x全面教程
    一、基础1.默认配置使用KestrelWebServerASP.NETCore内置——跨平台IIS集成UseIIS()UseIISIntergration()LogIConfiguration接口2.IConfiguration配置信息的来源appsettings.jsonUserSerets环境变量命令行参数XML...3.管道4.MVC5.路由RoutingConcentionalRoutingAttributeRou......
  • 质因子分解C++
    1、题目2、AC代码#include<iostream>#include<cmath>usingnamespacestd;constintmaxn=100010;//10的5次方即可boolisPrime(intn){if(n<=1)returnfalse;if(n==2||n==3)returntrue;//特判if(n%6!=1&&n%6!=5)returnfalse;//不在6的倍......
  • CSS选择器介绍
    1、三种基本选择器优先级:id选择器>类选择器>标签选择器/*标签选择器,可以作用于HTML里面的所有这种标签*/h1{ color:red; background-color:aquamarine; border-radius:5px;}p{ font-size:38px;}/*类选择器,.class类名,可以多个标签归类*/.xuexi{ color:blue......
  • 递推算法例题C++
    1、移动路线【题目描述】X桌子上有一个m行n列的方格矩阵,将每个方格用坐标表示,行坐标从下到上依次递增,列坐标从左至右依次递增,左下角方格的坐标为(1,1),则右上角方格的坐标为(m,n)。小明是个调皮的孩子,一天他捉来一只蚂蚁,不小心把蚂蚁的右脚弄伤了,于是蚂蚁只能向上或向右移动。小明......