C#基础--类/接口/成员修饰符,多态、重载、重写,静态和非静态
C#基础--类/接口/成员修饰符,多态、重载、重写,静态和非静态
类/接口/成员修饰符
C#修饰符---接口:
接口默认访问符是internal
接口的成员默认访问修饰符是public
C#修饰符--类:
public、internal、 partial、abstract、sealed、static
C#修饰符--类成员修饰符:
public、protected、private、internal、sealed、abstract、virtual、override、readonly、const
简单介绍:
Public:最开放,所有的本程序集以及其他的程序集里面的对象都能够访问
Protected:比较开放,自身成员以及子类成员可访问
Private:只有自身成员才能够访问
Internal:本程序集内的成员可以访问
Partial:部分类,可以将一个类分成几部分写在不同文件中,最终编译时将合并成一个文件,且各个部分不能分散在不同程序集中
Abstract:修饰类的时候表示该类为抽象类,不能够创建该类的实例。修饰方法的时候表示该方法需要由子类来实现,如果子类没有实现该方法那么子类同样是抽象类;且含有抽象方法的类一定是抽象类
Sealed:修饰类时表示该类不能够被继承,修饰方法时表示该方法不能被覆写。
Static:修饰类时表示该类时静态类,不能够实例化该类的对象,既然不能实例化该类,那么这个类也就不能够含有对象成员,即该类所有成员为静态;修饰类成员时,该成员为类成员,只能通过【类.成员名】的方式访问
当static修饰构造函数时,构造函数不能含有任何参数,不能含有修饰符,构造函数不能对对象成员进行初始化操作。但是能够对静态成员进行初始化或者调用。不能保证他在什么时候执行,却能保证在第一次使用类型前执行。在静态构造函数中初始化的静态成员为最终初始化结果。
Virtual:修饰方法成员,表示虚方法。父类可以含有该类的实现,子类可以覆写该函数。
Override:表示该方法为覆写了父类的方法。
Readonly:修饰字段,表示该字段为只读字段。
注意:readonly修饰引用类型时由于操作不当可能修改该只读对象状态。例如:
Readonly List< Person> persons=….;
我们可能在某些地方对persons 进行了修改:persons.add(new Person());
Const:修饰字段,表示该字段为只读字段。并且在编译时必须能够明确知道该字段的值,其值是硬编码到程序中去的,修改了该类型成员后需要重新编译才能使修改生效。
而readonly是运行时只读,内容在运行时确定,所以修改了readonly类型成员后无需重新编译即可生效。
Readonly不能修饰局部变量,const可以。
注意:当一个类或方法没有被任何修饰符修饰时,默认为internal:
多态、重载、重写
重写:是指重写基类的方法,在基类中的方法必须有修饰符virtual,而在子类的方法中必须指明override。
格式如下:
1.在基类中:
- public virtual void myMethod()
- {
- }
2.在子类中:
- public override void myMethod()
- {
- }
重写以后,用基类对象和子类对象访问myMethod()方法,结果都是访问在子类中重新定义的方法,基类的方法相当于被覆盖掉了。
重载:用于在给定了参数列表和一组候选函数成员的情况下,选择一个最佳函数成员来实施调用。
- public void test(intx,inty){}
- public void test(intx,refinty){}
- public void test(intx,inty,stringa){}
重载的特征:
- 方法名必须相同
- 参数列表必须不相同,与参数列表的顺序无关
- 返回值类型可以不相同
但如果有泛型,就要注意了!
多态:c#的多态性主要体现在类的继承上
子类继承父类的时候,可能出现同名但方法定义不同的情况, 所以在子类中会将原方法覆盖,实现自身的要求.
总结一句话:通过继承实现的不同对象调用相同的方法,表现出不同的行为,称之为多态。
需要注意的地方有两点:
- 可以在子类中被重写的方法一定要被标记成virtual(虚拟), abstract(抽象), override(重写)标记为virtual 和abstract 的函数就是为了重写而创建的,标记为override的函数本身是由前两种函数重写而来的,所以它可以被重写也是顺理成章的了;
- 重写的函数必须在子类中出现,而且任何一个父类的函数在其一个子类中只能被重写一次。(这一点很好理解,当你要重写两次时,该子类中将定义两个返回类型,方法名称 和参数列表都相同的函数,这肯定是不可能的)。
例子1:
- 代码
- public class Animal
- {
- public virtual void Eat()
- {
- Console.WriteLine("Animal eat");
- }
- }
- public class Cat : Animal
- {
- public override void Eat()
- {
- Console.WriteLine("Cat eat");
- }
- }
- public class Dog : Animal
- {
- public override void Eat()
- {
- Console.WriteLine("Dog eat");
- }
- }
- class Tester
- {
- static void Main(string[] args)
- {
- Animal[] animals = new Animal[];
- animals[] = new Animal();
- animals[] = new Cat();
- animals[] = new Dog();
- for (int i = ; i < ; i++)
- {
- animals[i].Eat();
- }
- }
- }
输出结果:
Animal eat...
Cat eat...
Dog eat...
在上面的例子中,通过继承,使得Animal对象数组中的不同的对象,在调用Eat()方法时,表现出了不同的行为。
多态的实现看起来很简单,要完全理解及灵活的运用c#的多态机制,也不是一件容易的事
例子2:override实现多态
多层继承中又是怎样实现多态的。比如类A是基类,有一个虚拟方法method()(virtual修饰),类B继承自类A,并对method()进行重写(override修饰),现在类C又继承自类B,是不是可以继续对method()进行重写,并实现多态呢?看下面的例子。
- 代码
- public class Animal
- {
- public virtual void Eat()
- {
- Console.WriteLine("Animal eat");
- }
- }
- public class Dog : Animal
- {
- public override void Eat()
- {
- Console.WriteLine("Dog eat");
- }
- }
- public class WolfDog : Dog
- {
- public override void Eat()
- {
- Console.WriteLine("WolfDog eat");
- }
- }
- class Tester
- {
- static void Main(string[] args)
- {
- Animal[] animals = new Animal[];
- animals[] = new Animal();
- animals[] = new Dog();
- animals[] = new WolfDog();
- for (int i = ; i < ; i++)
- {
- animals[i].Eat();
- }
- }
- }
运行结果为:
Animal eat...
Dog eat...
WolfDog eat...
在上面的例子中类Dog继承自类Animal,对方法Eat()进行了重写,类WolfDog又继承自Dog,再一次对Eat()方法进行了重写,并很好地实现了多态。不管继承了多少层,都可以在子类中对父类中已经重写的方法继续进行重写,即如果父类方法用override修饰,如果子类继承了该方法,也可以用override修饰,多层继承中的多态就是这样实现的。要想终止这种重写,只需重写方法时用sealed关键字进行修饰即可。
例子3:abstract-override实现多态
用abstract修饰的抽象方法。抽象方法只是对方法进行了定义,而没有实现,如果一个类包含了抽象方法,那么该类也必须用abstract声明为抽象类,一个抽象类是不能被实例化的。对于类中的抽象方法,可以再其派生类中用override进行重写,如果不重写,其派生类也要被声明为抽象类。看下面的例子。
- 代码
- public abstract class Animal
- {
- public abstract void Eat();
- }
- public class Cat : Animal
- {
- public override void Eat()
- {
- Console.WriteLine("Cat eat");
- }
- }
- public class Dog : Animal
- {
- public override void Eat()
- {
- Console.WriteLine("Dog eat");
- }
- }
- public class WolfDog : Dog
- {
- public override void Eat()
- {
- Console.WriteLine("Wolfdog eat");
- }
- }
- class Tester
- {
- static void Main(string[] args)
- {
- Animal[] animals = new Animal[];
- animals[] = new Cat();
- animals[] = new Dog();
- animals[] = new WolfDog();
- for (int i = ; i < animals.Length; i++)
- {
- animals[i].Eat();
- }
- }
- }
运行结果为:
Cat eat...
Dog eat...
Wolfdog eat...
从上面可以看出,通过使用abstract-override可以和virtual-override一样地实现多态,包括多层继承也是一样的。不同之处在于,包含虚拟方法的类可以被实例化,而包含抽象方法的类不能被实例化。
静态和非静态
静态类和非静态类
静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 new 关键字创建静态类类型的变量。在声明一个类时使用static关键字,具有两个方面的意义:首先,它防止程序员写代码来实例化该静态类;其次,它防止在类的内部声明任何实例字段或方法。
静态类是自C# 2.0才引入的,C# 1.0不支持静态类声明。程序员必须声明一个私有构造器。私有构造器禁止开发者在类的范围之外实例化类的实例。使用私有构造器的效果与使用静态类的效果非常相似。
两者的区别:
私有构造器方式仍然可以从类的内部对类进行实例化,而静态类禁止从任何地方实例化类,其中包括从类自身内部。静态类和使用私有构造器的另一个区别在于,在 使用私有构造器的类中,是允许有实例成员的,而C# 2.0和更高版本的编译器不允许静态类有任何实例成员。使用静态类的优点在于,编译器能够执行检查以确保不致偶然地添加实例成员,编译器将保证不会创建此 类的实例。静态类的另一个特征在于,C#编译器会自动把它标记为sealed。这个关键字将类指定为不可扩展;换言之,不能从它派生出其他类。
静态类的主要特性:
1:仅包含静态成员。
2:无法实例化。
3:是密封的。
4:不能包含实例构造函数。
静态成员
1:非静态类可以包含静态的方法、字段、属性或事件;
2:无论对一个类创建多少个实例,它的静态成员都只有一个副本;
3:静态方法和属性不能访问其包含类型中的非静态字段和事件,并且不能访问任何对象的实例变量;
4:静态方法只能被重载,而不能被重写,因为静态方法不属于类的实例成员;
5:虽然字段不能声明为 static const,但 const 字段的行为在本质上是静态的。这样的字段属于类,不属于类的实例。因此,可以同对待静态字段一样使用 ClassName.MemberName 表示法来访问 const 字段;
6:C# 不支持静态局部变量(在方法内部定义静态变量)。
静态构造函数
1:静态类可以有静态构造函数,静态构造函数不可继承;
2:静态构造函数可以用于静态类,也可用于非静态类;
3:静态构造函数无访问修饰符、无参数,只有一个 static 标志;
4:静态构造函数不可被直接调用,当创建类实例或引用任何静态成员之前,静态构造函数被自动执行,并且只执行一次。
注意:
1:静态类在内存中是一直有位置的;
2:非静态类在实例化后是在内存中是独立的,它的变量不会重复,在使用后会及时销毁,所以不会出现未知的错误。在C#中静态成员是比较敏感的东西,在不是十分确认的情况下不要使用;
3:建议更多地使用一般类(非静态类)。
使用选择:
当定义的类不需要进行实例化时,我们使用静态类;如果需要实例化对象,需要继承等特性时,应该使用非静态类,并且将统一使用的变量和方法设为静态的,那么所有实例对象都能访问。
C#基础--类/接口/成员修饰符,多态、重载、重写,静态和非静态的更多相关文章
- 如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?
出题者简介: 孙源(sunnyxx),目前就职于百度 整理者简介:陈奕龙,目前就职于滴滴出行. 转载者:豆电雨(starain)微信:doudianyu 若想令自己所写的对象具有拷贝功能,则需实现 N ...
- python - 类成员修饰符
在java,c#类的成员修饰符包括,公有.私有.程序集可用的.受保护的. 对于python来说,只有两个成员修饰符:公有成员,私有成员 成员修饰符是来修饰谁呢?当然是修饰成员了.那么python类的成 ...
- Python_day8_面向对象(多态、成员修饰符、类中特殊方法、对象边缘知识)、异常处理之篇
一.面向对象之多态 1.多态:简而言子就是多种形态或多种类型 python中不支持多态也用不到多态,多态的概念是应用与java/C#中指定传参的数据类型, java多态传参:必须是传参数的数据类型或传 ...
- Python菜鸟之路:Python基础-类(2)——成员、成员修饰符、异常及其他
三大成员 在Python的面向对象中,主要包括三大成员:字段.方法.属性 字段 类成员的字段又可分为普通字段.静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,代码示例如下: ...
- python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】
python_way day8 一.面向对象三大特性: 多态 二.面向对象中的成员 字段.方法属性 三.成员修饰符 四.特殊成员 __init__.__doc__.__call__.__setitem ...
- 06 面向对象:多态&抽象类&接口&权限修饰符&内部类
多态: /* 多态(polymorphic)概述 * 事物存在的多种形态 多态前提 * a:要有继承关系. * b:要有方法重写. * c:要有父类引用指向子类对象. * 成员变量 * 编译看左边(父 ...
- python学习day20 面向对象(二)类成员&成员修饰符
1.成员 类成员 类变量 绑定方法 类方法 静态方法 属性 实例成员(对象) 实例变量 1.1实例变量 类实例化后的对象内部的变量 1.2类变量 类中的变量,写在类的下一级和方法同一级. 访问方法: ...
- Python学习:17.Python面向对象(四、属性(特性),成员修饰符,类的特殊成员)
一.属性(特性) 普通方法去执行的时候,后面需要加括号,特性方法执行的时候和静态字段一样不需要不需要加括号. 特性方法不和字段同名. 特性方法不能传参数. 在我们定义数据库字段类的时候,往往需要对其中 ...
- 学习C#修饰符:类修饰符和成员修饰符
C#修饰符之类修饰符:public.internal. partial.abstract.sealed.static C#修饰符之成员修饰符:public.protected.private.inte ...
随机推荐
- 怎样使用ZOL一键安装器下载中关村在线的源安装包
怎样使用ZOL一键安装器下载中关村在线的源安装包 马根峰 (广东联合电子服务股份有限公司, 广州 510300) 摘要 中关村在线近期開始推出ZOL一键安装器,用户直 ...
- 奇怪吸引子---GenesioTesi
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- 坚果云无法同步SVN文件夹
把svn的库放在云盘上,同步到本地,以前在金山快盘.360网盘都用得好好的,换坚果云后,想着肯定没问题,结果发现,不行! 新机子上的版本库可以建起来,但检出时报错: Could not open th ...
- 利用 Express 托管静态文件
通过 Express 内置的 express.static 可以方便地托管静态文件,例如图片.CSS.JavaScript 文件等. 将静态资源文件所在的目录作为参数传递给 express.stati ...
- 【CLR】详解CLR中的程序集
目录结构: contents structure [+] 程序集的简介 为程序集分配强名称 如何指定程序集的版本资源信息 如何对程序集签名 全局程序集缓存 如何查看程序集的信息 强命名程序集防串改 1 ...
- Android UI系列-----ImageView的scaleType属性
这篇随笔将会简单的记录下ImageView这个控件的一些使用方法,以及其最重要的一个属性: scaleType ImageView这个控件是用来显示图片用的,例如我们可以通过下面这段xml配置来声明显 ...
- Android---Hellow World
在搭建好了Android的开发环境后,接下来要做的事情就是开始开发我们的第一个Android应用程序---Hello World. 1.我们新建一个android项目: Application Nam ...
- Java list对象列表排序 实例
package com.test; public class Bean { private String name; private int priority; public String getNa ...
- C# 给枚举类型增加一个备注特性
/// <summary> /// 备注特性 /// </summary> public class RemarkAttribute : Attribute { /// < ...
- Asp.Net 合并图片(二维码和其他图片合并)
需求:根据网址生成二维码,然后再把二维码生成到背景图片上,然后显示在网页中 pic.ashx <%@ WebHandler Language="C#" Class=" ...