C#笔记-NIIT-04
简单的解释抽象与封装,方法
session4
抽象和封装
使用访问指定符实现封装
方法
一 抽象和封装
封装和抽象是任何面向对象编程语言的重要特性。
抽象
抽象涉及仅抽取相关的信息
封装
封装涉及将一个或多个组件打包在一起
封装从字面上解释为“包围或者密封”
封装定义成将物理或逻辑包中的一个或多个项放入封套的过程
它防止对不需要的信息的访问
二 使用访问指定符实现封装
所有类型和类型成员都具有可访问性级别,用来控制是否可以在您程序集的其他代码中或其他程序集中使用它们。 可使用访问修饰符指定声明类型或成员时类型或成员的可访问性。
public
同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员。
private
只有同一类或结构中的代码可以访问该类型或成员。
只有同一类或结构或者此类的派生类中的代码才可以访问的类型或成员。
同一程序集中的任何代码都可以访问该类型或成员,但其他程序集中的代码不可以。
protected internal
由其声明的程序集或另一个程序集派生的类中任何代码都可访问的类型或成员。 从另一个程序集进行访问必须在类声明中发生,该类声明派生自其中声明受保护的内部元素的类,并且必须通过派生的类类型的实例发生。
类和结构的可访问性
直接在命名空间中声明的类和结构(即,没有嵌套在其他类或结构中的类和结构)可以是公共类和结构,也可以是内部类和结构。 如果不指定访问修饰符,则默认为 internal。
结构成员,包括嵌套的类和结构,可以声明为公共的、 内部的,或私人的。 类成员(包括嵌套的类和结构)可以为公共的、受保护的内部、受保护的、内部的或私有的。 类成员和结构成员的访问级别,包括嵌套类和结构,默认为私有。 不可以从包含类型之外访问私有嵌套类型。
派生类的可访问性不能高于其基类型。 换句话说,不能有从内部类 A 派生的公共类 B。 如果允许这种情况,将会使 A 成为公共类,因为 A 的所有受保护的成员或内部成员都可以从派生类访问。
可以使用 InternalsVisibleToAttribute 使其他某些程序集能够访问您的内部类型。
类成员和结构成员的可访问性
可以使用五种访问类型中的任何一种来声明类成员(包括嵌套的类和结构)。 结构成员无法声明为受保护成员,因为结构不支持继承。
通常,成员的可访问性低于包含成员的类型的可访问性。 如果由成员实现接口方法或重写已在公共基类中定义的虚拟方法时,内部类的公共成员可以从外部程序集访问。
任何成员的字段、 属性或事件的类型必须至少与该成员本身一样具备可访问性。 同样,作为方法、索引器或代表的任一成员的返回类型和参数类型必须至少有与该成员本身一样的可访问性。 例如,如果 C 不是公共类,则不能返回类 C 的公共方法 M。 同样,如果 A 声明为私有,则类型 A 不能有受保护的属性。
用户定义的运算符必须始终声明为公共运算符。
析构函数不能具有可访问性修饰符。
其他类型
直接用命名空间声明时,可以将接口声明为公共接口或内部接口,只与类和结构一样,接口默认具有内部可访问性。 接口成员始终是公共成员,因为接口的用途是让其他类型能够访问某个类或结构。 访问修饰符不能应用于接口成员。
枚举成员始终是公共的,不能应用任何访问修饰符。
委托行为类似于类和结构。 默认情况下,它们在命名空间中直接声明时具有内部访问权,在嵌套时具有私有访问权。
下面是老师上课的内容:
派生时,派生类自动获取基类(即父类)的所有成员
(但构造方法和析构方法除外, 它们不能被派生类继承)。其中①基类的public成员被派生类继承后在派生类中可以直接访问,也可以在程序的任何地方通过派生类的对象(针对实例成员:非static)或派生类名(针对静态成员)访问;
②基类的private成员不能在派生类中访问,也不能通过派生类的对象或派生类名访问;
③基类的protected成员只能在基类和派生类中访问,不过在派生类中不能通过基类的对象来访问。
另外,派生类中可以通过基类名或当前的派生类名访问基类中的静态protected成员。//====TestProtected.cs===================== class A { private int i = 0; protected int j = 0; public int k = 0; protected static int m = 0; } // 定义B类(A类的子类) class B : A { public void Method() { i = 1; // j = 2; // k = 3; // m = 4; // A a = new A(); //父类引用变量 (指向父类对象) a.j = 20; // B b = new B(); //子类引用变量 (指向子类对象) b.j = 20; // A.m = 40; // B.m = 400; // } } public class TestProtected { public static void Main() { B b = new B(); b.i = 11; //显然 b.j = 22; // b.k = 33; // b.Method(); } } //====TestProtected.cs结束=====================当派生类与基类的定义位于同一程序集时,基类的internal和protected internal成员与public成员表现是类似的(只是它们不能在另一个程序集中访问)。不过,当派生类与基类的定义在不同的程序集时,应该注意:
④基类的internal成员不能在位于另一个程序集的派生类中访问,也不能通过该派生类的对象或派生类名访问;
⑤基类的protected internal成员只能在所属的程序集及所属类的派生类中访问,不能通过位于另一个程序集的派生类对象或派生类名在派生类之外访问,也不能在位于另一个程序集的派生类中通过基类对象访问。
//==========A.cs========================== //〖编译〗使用:csc /t:library /out:A.dll A.cs // 或csc /t:library A.cs // 以生成 A.dll。 public class A { internal int i = 0; internal protected int j = 0; protected internal static int k = 0; } //==========A.cs结束========================== //=========== ProtectedInternal.cs================= //**首先,可以试着将两个文件一起编译 // csc /t:exe /out:ProInt.exe A.cs ProtectedInternal.cs //〖编译〗请用:csc /r:A.dll Test.cs // 能正确生成 Test.exe 吗? class B : A { public void Method() { i = 1; // j = 2; // k = 3; // A a = new A(); a.j = 20; // B b =new B(); b.j = 20; // A.k = 40; // B.k = 400; // } } //【独立】的测试类 ProtectedInternal public class ProtectedInternal { static void Main() { B b = new B(); b.i = 11; // b.j = 22; // b.k = 44; //▲【**一起编译,唯一出错位置】 B.k = 44; // } } //=========== ProtectedInternal.cs结束=================
方法放入下一篇中复习