C# 派生,virtual,sealed,new ,override,abstract,base

/*extends,sealed,override,new,virtual,abstract,base
 * 继承,密闭类,重写(覆盖),隐藏(hide),虚(可替换),抽象,调用父类成员
 * 重点:多态性(多种形态polymorphism):相同签名的成员在不同的类中有不同的实现,就被成为多态性,也只同一个签名有多个实现;
 * 派生/继承:对基类进行特化,包含附加的尘缘或对基类成员进行自定义,建立了“属于”这种关系。
 * 派生类型/子类型:继承了较常规类型的成员的特化类型
 * 基/超/父类型:其派生类型继承的常规类型
 * 继承的目的:为了扩展先有的类型来添加更多的功能(数据和行为)
 * 重构就是形而上学,派生就是形而下学
 * 派生类继承了除构造函数和析构函数以外的所有基类成员,但是继承并不意味这一定能访问,能访问的不一定就一定是继承下来的,比如可以通过base访问基类的构造
 * private规定就只能在类的内部进行访问
 * 基类中受保护的成员只能从基类及其派生类中访问;
 * 每个派生类都可作为它的任何基类的实例使用
 * protected internal等于是一个internal和protected的中和,所以访问级别比protected的大比internal的小,等于是protected的扩展,可以在类外访问
 * 密闭类sealed,用来放置别的类从它那继承,常见的密闭类如String,Void等
 * C#支持重写实例方法和属性,但不支持重写字段或者任何静态成员,不支持字段好理解因为字段没有实现;
 * 静态成员不能标记为override,virtual或abstract
 * 字段不能被标记为abstract,virtual,override,所以说抽象类里面的成员不可能都是抽象的
 * 为了支持重写,必须将允许重写的每个成员标记为virtual,换句话说,vitrual标志着方法或属性可在派生类中被替换(重写,覆盖)
 * 对应的override以为这派生类的实现会替换基类的实现,new会隐藏掉基类的实现
 * 用override修饰的任何成员会自动成为虚成员,其他子类能进一步“特化”它的实现,这也就是为什么用override重写了的成员还可以在派生类中继续重写的原因
 * “运行时”遇到虚方法时,它会调用虚成员派生的最远的重写;
 * 只有实例成员才可以是virtual的;
 * 规范:虚方法只提供默认实现,而且必须有实现;这种实现完全可以由派生类重写,所以必须事先想好是否得要virtual
 * C#不允许隐式重写,必须显示的进行重写
 * 重点:当重写public继承成员时无法修改它的访问修饰符,当重写protected internal继承成员时,无法更改访问修饰符,当重写internal继承成员时,无法更改访问修饰符
 * 重点:当使用override重写继承成员时,是不能更改访问修饰符的,override也可以修改返回值类型
 * C#中没有虚类这一说法
 * 抽象类:抽象类中可以没有抽象成员,但是抽象类中可以有所有的种类的成员:static,instantial,virtual,abstract等等,但是如果一旦某一个类中出项了抽象成员的话,
 * 那么这个类必须是抽象的;
 * 重点:虚拟成员和抽象成员不能使私有的;
 * new(hide)不需要显示的标明什么,跟override不一样,要使用override重写的话必须要显示的说明,new是直接隐藏不需要说明什么;
 * new可以修改访问级别,可以修改返回值类型,new 隐藏不了继承下来的私有成员
 * sealed:为类使用sealed修饰符是为了禁止从该类继承,类似的虚成员也可密封,这会禁止子类重写继承链中高层基类的虚成员;
 * 子类B重写了基类中的成员,但是不想让子类B的派生类重写的话,就使用sealed阻止它的派生类重写它所重写的成员,也就是在重写的时候才能使用sealed
 * 抽象类的构造默认是internal的
 * 私有成员派生类是看不见的,所以不能标记为override或abstract
 * 英语学习:critical批评的,爱挑剔的; 关键的; 严重的; 极重要的; inherited继承的,遗传的,通过继承得到的;override推翻,无视; 践踏; 优先于; 覆盖;
 * intend意愿;sealed密封,密封的,未知的;
 * User: YuanWei
 * Date: 2015/1/17
 * Time: 23:13
 *
 */
using System;

namespace LearningExtends
{
    class Program
    {
        public static void Main(string[] args)
        {
            // TODO: Implement Functionality Here
            Chinese chinese=new Chinese("ZhangSan",23);
            chinese.Say();
            chinese.Fight();
            chinese.Age=24;//可以访问internal protected成员
            Person person=new Person();
            person.Fight();
            ShanXi shanxi=new ShanXi();
            Console.WriteLine(shanxi.Say());
            Console.ReadKey(true);
        }
    }
    public class Person
    {
        public Person()
        {
        }
//        public virtual void ppp();//错误,必须声明主题,因为它为标记为abstract,extern或partial
        public Person(string name,int age)
        {
            Name=name;
            Age=age;
        }
        /*protected修饰符
         *只可以在本类或者是派生类中访问
         */
//        也可以写成相反的情况internal protected int Age{get;set;}
        protected internal int Age{get;set;}
        protected  virtual string Name{get;set;}//virtual可以修饰属性
        protected internal virtual void Love()
        {
            System.Console.WriteLine("I can love ,I am a loving of Person");
        }
        internal virtual void Teach()
        {
            System.Console.WriteLine("I am a teacher of person");
        }
        public virtual void Fight()
        {
            System.Console.WriteLine("I am a Fighting of Preson");
        }
//        private virtual void PlayGame()//错误:虚拟成员或抽象成员不能是私有的
//        {
//        }
        private void Smile()
        {
            System.Console.WriteLine("I am a smiler of person");
        }
        public void Talk()
        {
            Console.WriteLine("I am {0}",Name);
        }
//        public sealed virtual void Miss()//错误:因miss()方法不是重写,所以无法将其密封,换句话来说,子类B重写了基类中的成员,但是不想让子类B的派生类重写的话,
        //就使用sealed阻止它的派生类重写它所重写的成员
//        {
//
//        }
    }
    public class Chinese:Person
    {
        public  Chinese(string name,int age):base(name,age)
        {
        }
        public Chinese()
        {
        }
//        private new  void Smile()//警告:不会隐藏继承的成员。不需要new keyword,说明继承下来的private成员是不能被隐藏掉的
//        {
//        }
//        public override void Fight()重写基类的Fight()方法
//        {
//            base.Fight();//调用基类的Fight()方法
//        }
//        protected override string Name {//重写基类的属性
//            get {
//                return base.Name;
//            }
//            set {
//                base.Name = value;
//            }
//        }
        public  new string Name{get;set;}//hide,用protected时可以更换访问级别
//        protected override void Fight()//错误,当重写public继承成员时,无法更改访问修饰符
//        {
//            System.Console.WriteLine("I am a Fighting of Chinese");
//        }
        public  override void Fight()
        {
            System.Console.WriteLine("I am a Fighting of Chinese");
        }
        public void Say()
        {
            System.Console.WriteLine("My name is {0},Age is{1}",Name,Age);
        }
//        public override void Love()//错误,当重写protected internal继承成员时,无法更改访问修饰符
//        {
//            System.Console.WriteLine("I am a loving of Chinese");
//        }
//        public  override  void Teach()//错误,当重写internal继承成员时,无法更改访问修饰符
//        {
//            System.Console.WriteLine("I am a teacher of Chinese");
//        }
        /*总结:当用override进行重写时,是不能更改访问修饰符的
         *
         */
//        public virtual static int NumOfPeople{get;set;}//会报错,静态成员不能标记为override,virtual或abstract
//        public override int NumOfPepple;//错误,字段不能被标记为abstract,virtual,override
    }
    public class ShanXi:Chinese
    {
        public ShanXi()
        {
        }
        /*new的用法:
         *
         */
//        public new void Say()//new直接有意隐藏掉基类的东西
//        {
//        }
//        private new void Say()//说明new操作符可以更改基类的访问级别
//        {
//        }
        public new string Say()//说明new可以修改返回值类型
        {
            return "Use new keyword can modify type of the return value";
        }
        /*但是如果用new关键字的话相同的方法签名,但是返回值类型和参数列表不一样的话,就不是重写了就只会报警告,不会隐藏掉基类继承的成员
         *
         */
        public override void Fight()
        {
            System.Console.WriteLine("I am a Fighting of ShanXi ");
        }
//        public override void Fight(string name)//错误:没有找到合适的方法进行重写,说明重写顶多就是返回值类型和实现不一样而已
//        {
//            System.Console.WriteLine("I am a Fighting of ShanXi ");
//        }
//        public override string ToString()//说明override也可以修改返回值类型
//        {
//            return "Use override keyword can modify type of the return value";
//        }
        public void Speak()
        {
            /*从这里可以看出派生类继承了除构造和析构之外的所有的成员,因此在这个地方可以访问到Name
             *但是Name是protect所以还是只能在类中进行访问,出了这个类就访问不了了;
             */
            Console.WriteLine("I can also speak my name is {0}",Name);
        }
    }
//    public virtual class BeiJing
//    {
    //错误:在C#中没有虚类这一说法;
//    }
    public abstract class Human
    {
//        private abstract int NumOfPepple;//错误,字段不能是abstract的
        public static int NumOfPepple;//抽象类里面可以包含静态成员
        public static void SayHello()
        {
            System.Console.WriteLine("I am a human, I am a static member");
        }
        public virtual void Talk()//抽象类里面可以包含虚成员
        {
            System.Console.WriteLine("I can talk, I am a virtual member");
        }
        public void Do()//抽象类中可以包含实例成员
        {
            System.Console.WriteLine("I can do erveyting, I am a instantial member");
        }
//        public virtual abstract void Kiss();//错误,抽象方法不能标记为virtual
//        public abstract virtual void Kiss();//错误
//        public virtual override void Kiss(){}//错误:override的成员不能标记为new或virtual
        /*总结:所以说只有实例成员才可以是virtual的,*/

    }
}
时间: 2024-08-19 12:38:04

C# 派生,virtual,sealed,new ,override,abstract,base的相关文章

Partial(部分方法,局部方法),virtual(虚方法),abstract(抽象方法)

Partial 部分方法顾明思议是方法的一部分,不完整的,在ide编译时候,会将所有部分方法加载到一起统一编译,如果分部方法没有被实现,编译器就不会.对他们进行编译. 局部类型的限制 (1) 局部类型只适用于类.接口.结构,不支持委托和枚举.(2) 同一个类型的各个部分必须都有修饰符 partial.(3) 使用局部类型时,一个类型的各个部分必须位于相同的命名空间中.(4) 一个类型的各个部分必须被同时编译. 3. 局部类型的注意点 (1) 关键字partial是一个上下文关键字,只有和 cla

c#什么时候使用virtual什么时候使用abstract

一.C#中virtual与abstract的区别(引用"姓吕名布字子乔"的文章) C#的virtual & abstract经常让人混淆,这两个限定词都是为了让子类进行重新定义,覆盖父类的定义.但是用法上差别很大. a)     virtual修饰的方法必须有方法实现(哪怕只有一对大括号),abstract修饰的方法不能有实现. b)    virtual可以被子类重写,abstract必须被子类重写 c)     如果类中的某一函数被abstact修饰,则类名也必须用abst

C++虚函数virtual,纯虚函数pure virtual和Java抽象函数abstract,接口interface与抽象类abstract class的比较

由于C++和Java都是面向对象的编程语言,它们的多态性就分别靠虚函数和抽象函数来实现. C++的虚函数可以在子类中重写,调用是根据实际的对象来判别的,而不是通过指针类型(普通函数的调用是根据当前指针类型来判断的).纯虚函数是一种在父函数中只定义而不实现的一种函数,不能用来声明对象,也可以被称为抽象类.纯虚函数的实现也可以在类声明外进行定义.C++中的抽象类abstract class是指至少有一个纯虚函数的类,如果一个类全部由纯虚函数组成,不包括任何的实现,被称为纯虚类. Java中的普通函数

python 用abc模块构建抽象基类Abstract Base Classes

见代码: 1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # @Time : 2018/08/01 16:58 4 from abc import ABCMeta, abstractmethod 5 6 7 class SClass(object): 8 __metaclass__ = ABCMeta 9 10 @abstractmethod 11 def my_print(self): 12 pass 13 14 15 class C0C

c#中abstract、override、new、virtual、sealed使用和示例

原文地址:http://blog.csdn.net/richerg85/article/details/7407544 abstract      修饰类名为抽象类,修饰方法为抽象方法.如果一个类为抽象类,则这个类智能是其他某个类的基类.抽象方法在抽象类中没有函数体.抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽象方法. 抽象类有如下特征: 抽象类不能实例化 抽象类的派生类必须实现所有抽象方法 抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽象方法 抽象方法:

C#基础知识(base、this、new、override、abstract、virtual、static)

前言 本文主要来讲解一下C#中,自己觉得掌握的不怎么样或者用的不多,不太熟悉的关键字,主要包括base.this.new.override.abstract.virtual以及针对static字段和static构造函数之间的执行问题. base关键字 base 关键字用于在派生类中实现对基类公有或者受保护成员的访问,但是只局限在构造函数.实例方法和实例属性访问器中: 调用基类上已被其他方法重写的方法. public class Father { public virtual void Say()

C#--virtual,abstract,override,new,sealed

virtual:使用此关键字,可以使其在派生类中被重写. abstract:抽象方法,由子类重写,或继续为抽象方法存在,并由其子子类实现. override: 重写父类方法,属性,或事件的抽象实现或虚方法. new:显式隐藏从父类继承的成员. 后台代码: public abstract class Animal { public abstract void Eat(); public virtual void Sleep() { HttpContext.Current.Response.Writ

virtual abstract override

virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义. 它们有一个共同点:如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的.毕竟加上virtual或abstract就是让子类重新定义的,而private成员是不能被子类访问的. 但是它们的区别很大.(virtual是“虚拟的”,abstract是“抽象的"). (1)virtual修饰的方法必须有实现(哪怕是仅仅添加一对大括号),而abstract修饰的方法一定不

C# onverride、abstract、vitrtual、new、sealed

abstract: 抽象方法是隐式的虚方法 在抽象方法声明中,不能使用static或者virtual修饰符 override: override关键字提供派生类对基类方法的新的实现,重写的基类方法必须和基类的方法有着相同的签名(函数名.返回值.参数列表相同). override关键字不可以重写基类非virtual修饰的方法和static修饰的静态方法.派生类的override方法重写的基类方法必须是virtual.abstract或者override的. 派生类的override方法和基类的vi