`

C#学习笔记——面向对象——类的继承

 
阅读更多

类继承

基类,派生类

public class MyClass:MyBase

{

 

}

 

C#中所有类的基类System.Object类(别名object

 

C#为单继承

编译器不允许派生类的可访问性高于基类。即内部类可以继承一个公共基类,但公共类不能继承一个内部类。

 

 

隐藏基类成员

派生类不能删除它继承的任何成员,但它可以隐藏基类成员。

要隐藏一个继承的数据成员,需要声明一个新的相同类型的成员,并使用相同的名称。

通过在派生类中声明新的带有相同前面的函数成员,可以隐藏或掩盖继承的函数成员。注:签名由名称和参数列表组成,但不包括返回类型。

使用new修饰符故意隐藏继承的成员。没有new修饰符,程序可以成功编译。但会产生一个警告。说明隐藏了一个基类成员。

也可以隐藏静态成员。

 

例:

隐藏基类成员

 

public class MyBaseClass

{

    string Field1;

}

 

 

 

public class MyDerivedClass: MyBaseClass

{

    new string Field1;  //用同样的名称掩盖基类成员

}

 

 

 

 

隐藏基类方法

public class MyBaseClass

{

  public void DoSomething()

{

 

}

}

 

 

public class MyDerivedClass: MyBaseClass

{

    new public void DoSomething()

    {

}

}

 

 

 

基类访问

有时派生类需要访问被隐藏的继承成员。可以使用基类访问表达式访问隐藏的基类成员。

基类访问表达式 由关键字base后面跟着一个点和成员的名称组成:  base.成员名称

 

使用基类的引用

派生类的实例由基类的实例加上派生类附加的成员组成。派生类的引用指向整个类对象,包括基类部分。

 

如果有一个派生类对象的引用,就可以获取该对象基类部分的引用,使用类型转换运算符把该引用转换为基类类型。类型转换运算符放置在对象引用的前面,用圆括号括起来的要被转换成的类名组成。

 

MyDerivedClass derived=new MyDerivedClass();  //创建一个对象  通过派生类

MyBaseClass mybc=(MyBaseClass)derived;          //转换引用        派生类对象转换为基类

 

derived对象可以访问从new MyDerivedClass()语句创建的实例的所有部分。

mybc只能访问new MyDerivedClass()语句创建实例的基类相关的部分。

 

 

虚方法和覆写方法

虚方法可以使基类的引用访问“升至”派生类内。(注:不使用虚方法,当使用基类引用访问派生类对象时,得到的是基类的成员。)

可以使用基类引用调用派生类的方法,只需满足:

派生类的方法和基类方法有相同的签名和返回类型。

基类的方法使用virtual标注。

派生类的方法使用override标注。

 

class MyBaseClass

{

    virtual public void Method()

    {}

}

 

 

class MyDerivedClass:MyBaseClass

{

    override public void Method()

    {}

}

 

 

 

class Program{

 

    static void main(){

        MyDerivedClass derived=new MyDerivedClass();  

        MyBaseClass mybc=(MyBaseClass)derived;    

        derived.Method();    //调用MyDerivedClass的方法

        mybc.Method();        //调用MyDerivedClass的方法

    }

 

}

 

 

覆写和被覆写的方法必须有相同的访问性。

不能覆写static方法或非虚方法。

方法、属性、索引、事件都可以被声明为virtual和override。

 

 

覆写标记为override的方法

覆写方法可以在继承的任何层次出现。

当使用对象基类部分的引用调用一个覆写的方法时,方法的调用被沿派生层次上溯执行,一直到标记为override的方法的最派生版本。

如果在更高的派生级别有该方法的其他声明,但没有被标记为override,那么它们不会被调用。

 

例:

 

class MyBaseClass

{

    virtual public void Method()

    {}

}

 

 

class MyDerivedClass:MyBaseClass

{

    override public void Method()

    {}

}

 

 

 

class MySecondClass:MyDerivedClass

{

    override public void Method()

    {}

}

 

 

 

 

class Program

{

    static void main(){

        MySecondClass derived=new MySecondClass();  

        MyBaseClass mybc=(MyBaseClass)derived;

        derived.Method();    //调用MySecondClass的方法

        mybc.Method();        //调用MySecondClass的方法

    }

}

 

 

 

例:

 

 

class MyBaseClass

{

    virtual public void Method()

    {}

}

 

 

class MyDerivedClass:MyBaseClass

{

    override public void Method()

    {}

}

 

 

 

class MySecondClass:MyDerivedClass

{

    new public void Method()

    {}

}

 

 

 

 

class Program

{

    static void main(){

        MySecondClass derived=new MySecondClass();  

        MyBaseClass mybc=(MyBaseClass)derived;

        derived.Method();    //调用MySecondClass的方法

        mybc.Method();        //调用MyDerivedClass的方法

    }

}

 

 

 

 

 

构造函数的执行

要创建对象的基类部分,基类的一个构造函数被作为创建实例过程的一部分被调用。

继承层次链中的每个类在执行它自己的构造函数体之前执行执行它的基类构造函数。

 

对象构造的顺序:

初始化实例成员。-->调用基类构造函数。-->执行实例构造函数的方法体。

 

注意:

在构造函数中调用虚方法是极不推荐的。在基类的构造函数被执行时,基类的虚方法会调用派生类的覆写方法,但这是在派生类的构造函数方法体被执行之前。因此,调用会在派生类没有完成初始化之前传递到派生类。

 

 

构造函数初始化语句

默认情况下,在对象被构造时,基类的无参数构造函数被调用。但构造函数可以被重载,所有基类可能有一个以上的构造函数。如果希望派生类使用一个指定的基类构造函数,必须在构造函数初始化语句中指定它。

有两种形式的构造函数初始化语句:

1.使用base并指明使用哪一个基类。

2.使用this并指明应该是一当前类的哪一个另外的构造函数。

 

基类构造初始化语句放在冒号后面,冒号后跟类的构造函数声明的参数列表。构造函数初始化语句由关键字base和要调用的基类构造函数的参数列表组成。

 

 

例:

 

指定基类的构造函数

class MyClass:MyBaseClass

{

    public MyClass(int i,int j):base(i)

{

 

}

}

 

 

使用this调用非默认构造器

class MyClass:MyBaseClass

{

    public MyClass():this (i,j)

{

 

}

 

public MyClass(int i,int j):base(i)

{

 

}

 

}

 

若没有给构造函数指定构造函数初始化器,编译器会自动添加base()

 

 

类访问修饰符

类的访问修饰符有两个级别:internal ,public

 

标记为public的类可以被系统内任何程序集中的代码访问。

 

public class MyClass

{

 

}

 

 

标记为internal的类只能被它自己所在的程序集内的类看到。

这是默认的可访问级别。所以,除非在类的声明中显示地指定修饰符public,程序集外部的代码不能访问该类。

可以使用internal访问修饰符显示地声明一个类为内部的。

 

internal class MyClass

{

 

}

 

 

 

 

程序集间的继承

C#允许从一个在不同的程序集内定义的基类派生类。要做到这一点,必须满足:

基类必须被声明为public,这样它才能被从它所在的程序集外部访问。

必须在Visual Studio工程中包括对包含该基类的程序集的引用。

 

为了使引用其他程序集中的类和类型更容易,不使用它们的完全限定名称,在源文件的顶部放置一个using指令

 

 

 

 

成员访问修饰符

 

 

 

public 公有的

protected 受保护的

internal protected 受内部保护的

private 私有的

internal 内部的

 

 

所有显示声明在类的声明中的成员都是相互可见的。

必须对每个成员指定访问级别。如果不指定某个成员的访问级别,它的隐式访问级别为private。

成员不能比它的类更可访问。即如果一个类的可访问性限于它所在的程序集,那么类的成员个体也不能从程序集外部看到。无论它的访问修饰符是什么。

 

访问成员的区域

 

public 公有的

所有类,程序集内部的类和外部的类都可以自由访问成员。

 

protected 受保护的

程序集外部不可访问,字段所在类可访问,字段所在类的派生类可访问。

 

internal protected 受内部保护的

对所有继承该类的类以及所有程序集内部的类可访问。

 

private 私有的

只能被自己的类的成员访问。

 

internal 内部的

对程序集内部的所有类可访问,但对程序集外部的类不可访问。

 

 

抽象成员

抽象成员是被设计来被覆写的函数成员。抽象成员有以下特征:

用abstract修饰符标记。

没有实现代码块。抽象成员的代码块被分号代替。

 

abstract public void PrintStuff(string s);

 

abstract public int MyProperty

{

    get;

    set;

}

 

 

不能把virtual修饰符加到abstract修饰符。

派生类中抽象方法的实现必须指定override修饰符。

抽象成员只能被声明在抽象类中。

 

 

 

抽象类

抽象类只能被用作其他类的基类。抽象类就是被设计来被继承的。

不能创建抽象类的实力

抽象类使用abstract修饰符。

 

抽象类可以包含抽象成员,但不必须。抽象类的成员可以是抽象成员和普通带实现的成员的任意组合。

抽象类自己可以派生自另一个抽象类。任何派生自抽象类必须使用override关键字实现该类所有的抽象成员,除非派生类自己也是抽象类。

 

 

密封类

密封类只能被用作独立的类,它不能被用作基类。

密封类使用sealed修饰符标注。

 

静态类

静态类的所有成员都是静态的。静态类用于封装不受实例数据影响的数据和函数。  静态类的一个普通的用途可能就是创建一个包含一组数学方法的数学库。

类本身必须标记为static。

类的所有成员必须是静态的。

类可以有一个静态构造函数,但没有实例构造函数,不能创建该类的实例。

不能继承静态类,它们是密封的。

 

 

扩展方法

如果不能修改类。例如该类在第三方类库中,那么只要它不是密封类,就能把它用作一个基类并在派生自它的类中实现这个增加的方法。

如果不能修改类,类又是密封的,或有其他的设计原因使这些方法不能工作,那么不得不在另一个类中使用该类的公有成员编写一个方法。

 

扩展方法必须被声明static。

扩展方法声明所在的类必须声明为static。

扩展方法必须包含关键字this作为它的第一个参数实型,并在后面跟着它所扩展的类的名称。

static class ExtendMyData

{

    public static double Average(this MyDate md){

       ....

    }

}

 

例:

namespace ExtensionMethods

{

    sealed class MyData

    {

        private double D1,D2,D3;

        public MyData(double d1,double d2,double d3)

        {D1=d1;D2=d2;D3=d3;}

 

        public double Sum(){return D1+D2+D3;}

    }

    static class ExtendMyData

    {

        public static double Average(this MyDate md){

            return md.Sum()/3;

        }

    }

}

 

 

class Progarm

{

    static void Main()

    {

        MyData md=new MyDate(3,4,5);

 

        Console.WriteLine("Sum:    {0}",md.Sum());

        Console.WriteLine("Average:{0}",md.Average());

    }

}

 

 

 

 

外部方法

外部方法是在声明中没有实现的方法。常常用于C#之外的语言编写的。

外部方法是用extern修饰符标记,而且类的声明中没有实现。最后跟分号。

声明和实现的连接是依赖实现的,但常常使用DllImport特性完成。

例:调用Win32 API

using System;

using System.Text;

using System.Runtime.InteropServices;

 

namespace ExternalMethod

{

    class MyClass

    {

        [DllImport(""kernel32,SetLastError=true)]

        public static extern int GetCurrentDirectory(int a,StringBuilder b);

    }

 

    class Progarm

    {

        static void Main()

        {

            const int MaxDirLength=250;

            StringBuilder sb=new StringBuilder();

            sb.Length=MaxDirLength;

 

            MyClass.GetCurrentDirectory(MaxDirLength,sb);

            Console.WriteLine(sb);

        }

    }

}

 

 

 

 

 

分享到:
评论

相关推荐

    C#6.0学习笔记 从第一行C#代码到第一个项目设计周家安著

    2. **面向对象编程**:C#是面向对象的语言,书中会详细讲解类、对象、封装、继承、多态等核心概念。了解这些概念有助于理解如何组织和设计复杂的代码结构。 3. **C# 6.0新特性**:C# 6.0引入了许多新特性,如自动...

    课件 C# 共2——02

    2. **C#_05_1.ppt 和 C#_05-1.ppt**:这些文件可能讨论的是同一主题的不同部分,可能是第五章的内容,可能涵盖类和对象的概念,这是面向对象编程的核心。这部分可能讲解了类的定义、对象的创建、属性、方法、构造...

    c#学习笔记.txt

    c#学习笔记(1) 51099在线学习网发布 文章来源:网络收集 发布时间:2006-05-25 字体: [大 中 小] 51099在线学习网 http://www.51099.com 1, 结构(struct) 与 类(class) [attributes] [modifiers] struct ...

    c#笔记本(源码程序)

    2. **面向对象编程**:讲解类、对象、继承、多态等概念,这是C#的核心特性,也是理解其强大之处的关键。 3. **Windows Forms应用**:通过创建用户界面,学习如何利用C#进行桌面应用开发。 4. **LINQ查询**:学习语言...

    C#——wpf入门经典

    C#入门经典:学习笔记 面向对象编程 C#是一种面向对象的语言,具有封装、继承、多态等特性。所有的类型可以看作是一个对象,C#只允许单继承,即一个类不会有多个基类。 .NET 框架 .NET 框架包括四个部分:类型...

    .net上课笔记资料精华

    【.NET 上课笔记资料精华】本篇笔记主要围绕 C# 中的核心概念——面向对象编程展开,涵盖了类的定义、对象的创建与使用、分部类、结构与类以及命名空间等多个方面,旨在帮助初学者深入理解面向对象编程的基础。...

    C#-Halcon-Python-C++练习文本笔记.zip

    C++的学习包括理解指针、内存管理、模板、STL(标准模板库)以及面向对象设计原则,如封装、继承和多态。 通过这个压缩包中的练习文本笔记,你可能会发现如何在C#、Python和C++中分别使用Halcon的API,以及在不同...

    适合初学者的资料发送到

    Java的学习从其特性——“一次编写,到处运行”开始,理解面向对象编程的概念,如类、对象、封装、继承和多态。深入学习包括异常处理、集合框架、IO流、线程、网络编程以及Java Swing或JavaFX进行GUI(图形用户界面...

    molaide笔记详细

    C#是一种完全面向对象的语言,支持类、对象、接口、继承、多态等面向对象特性。类是C#中的核心概念,用于封装数据和方法;对象则是类的实例,具备类定义的所有属性和行为。继承允许子类继承父类的属性和方法,多态则...

    Unity5实战:使用C#和Unity开发多平台游戏 源码

    此外,C#的面向对象特性,如类、继承、接口和抽象类,也是编写高效代码的重要工具。 在多平台游戏开发中,Unity5提供了一站式解决方案。无论是移动设备(iOS、Android)、桌面平台(Windows、Mac、Linux)还是游戏...

    CSharpAdvancedModule_OOP:SoftUni

    本资源包,名为"CSharpAdvancedModule_OOP:SoftUni",显然是针对SoftUni(软件大学)的C#高级模块——面向对象编程的学习资料。在这个模块中,你将深入理解并掌握C#中面向对象编程的核心概念和实践技巧。 面向对象...

    LINQ中文教程—很详细介绍LINQ

    在C# 2008的学习笔记中,会更深入地介绍命名空间的使用,以及两种编程方式——面向对象的API和基于LINQ的查询表达式——来处理XML文档。 通过这个详细的LINQ教程,你将全面掌握如何利用LINQ的强大功能来处理各种...

    NET初学者经典学习文档课程4

    在面向对象编程(OOP)中,继承是核心概念之一,它允许一个类(子类或派生类)从另一个类(父类或基类)继承属性和方法。这样可以实现代码的复用,提高程序的可维护性和扩展性。在.NET中,C#语言提供了强大的继承...

    极品资源代码

    学习这个项目,开发者可以深入理解C#的基本语法和面向对象编程思想,还能掌握如何使用C#进行文件操作、UI设计和事件驱动编程。对于想要提升C#编程技能的初学者来说,这是一个非常有价值的资源,因为它展示了如何用...

    我的学习笔记

    - **ADO.NET**: 基于.NET Framework设计,采用面向对象的编程模型,使用C#或VB.NET等语言进行开发更为自然。ADO.NET的数据绑定机制使得数据的展示和操作更加简单直观,减少了编码量,提高了开发效率。 总的来说,...

    程序设计课程项目实验报告1

    程序设计课程项目实验报告主要围绕使用XAML和C#开发Windows桌面应用——一款名为"Wind桌面日历"的软件进行,旨在提升学生的编程能力和面向对象的思维。在实验过程中,学生需要掌握WPF(Windows Presentation ...

    brendan-code:布伦丹笔记和代码从复兴训练

    C# 是一种面向对象的编程语言,由微软公司开发,主要用于Windows平台的应用程序开发,尤其是.NET框架。C#语言特性包括类、接口、继承、泛型、委托等,也支持异步编程、LINQ等高级特性。这个标签说明了项目主要涉及的...

Global site tag (gtag.js) - Google Analytics