《C#入门经典》学习笔记(定义类成员)

定义类成员

 

成员定义

在类定义中,也提供了该类中所有成员的定义,包括域、方法和属性
所有成员都有自己的访问级别:
public:成员可以由任何代码访问
private:成员只能由类中的代码访问(默认)
internal:成员只能由定义它的工程(装配件)内部的代码访问
protected:成员只能由类或派生类中的代码访问
protected internal:成员只能由工程(装配件)中派生类的的代码访问

域、方法和属性都可以使用关键字static来声明,表示静态成员


定义域

域用标准的变量声明格式和前面介绍的修饰符来说明
例如:
class MyClass
{
   public int MyInt;
}
注意:公共成员推荐用PascalCasing命名模式,私有成员可以用camelCasing命名模式

域可以使用readonly关键字,表示域只能在只能在执行构造函数的过程中赋值,或由初始化赋值语句赋值
例如:
class MyClass
{
   public readonly int MyInt = 17;
}

用static表示静态成员
例如:
class MyClass
{
   public static int MyInt;
}
静态域可以通过定义他们的类来访问,而不能通过对象实例来访问


通过const来创建一个常量
const成员也是静态的,不过不需要用static修饰


定义方法

方法使用标准函数格式,以及可访问性和可选的static修饰符来声明
例如:
class MyClass
{
   public string GetString()
   {
      return "Here is a string.";
   }
}

注意:如果使用了static就只能通过类来访问

其他关键字
virtual:方法可以重写
abstract:方法必须重写(只用于抽象类)
override:方法重写了一个基类方法
extern:方法定义放在其他地方

例如:
public class MyBaseClass
{
   public virtual void DoSomething()
   {
      // Base implementation.
   }
}

public class MyDerivedClass : MyBaseClass
{
   public override void DoSomething()
   {
      // Derived class implementation, overrides base implementation.
   }
}

如果使用了override,可以使用sealed指定这个方法不能在派生类中重写
例如:
public class MyDerivedClass : MyBaseClass
{
   public override sealed void DoSomething()
   {
      // Derived class implementation, overrides base implementation.
   }
}

使用extern可以提供方法在工程外部使用的代码


定义属性

属性有两个类似于函数的块,一个用于获取属性的值,另一个用于设置属性的值

两个块分别用get和set关键字来定义
可用于控制对属性的访问级别,忽略get块创建只写属性,忽略set块创建只读属性
这只适用于外部代码,因为类中代码可以访问这些块能访问的数据
属性至少包含一个块,才是有效的

属性基本结构包括准访问修饰关键字(public、private等)、后跟类名、属性名和函数块
例如:
public int MyIntProp
{
   get
   {
      // Property get code.
   }
   set
   {
      // Property set code.
   }
}

Get块必须有一个属性类型的返回值
简单的属性一般与一个私有域相关联,以控制对这个域的访问
例如:
// Field used by property.
private int myInt;
  
// Property.
public int MyIntProp
{
   get
   {
      return myInt;
   }
   set
   {
      // Property set code.
   }
}
这样外部代码就必须通过属性来访问这个私有域

Set函数以类似方式把一个值赋給域
可以使用关键字value引用用户提供的属性值
例如:
// Field used by property.
private int myInt;
  
// Property.
public int MyIntProp
{
   get
   {
      return myInt;
   }
   set
   {
      myInt = value;
   }
}
value等于与属性的类型向同的值

属性更大的作用在于对操作进行更多的控制
例如:
set
{
   if (value >= 0 && value <= 10)
   myInt = value;
}

如果使用了无效的值,有四种处理方法:
1 什么也不做(如上例)
2 给域赋默认值
3 继续执行,但记录该事件
4 抛出一个异常

通常使用后面两种
例如:
set
{
   if (value >= 0 && value <= 10)
      myInt = value;
   else
      throw (new ArgumentOutOfRangeException("MyIntProp", value, "Error!"));
}

可以在使用属性的代码中通过try...catch...finally来处理

属性可以使用virtual,override和abstract关键字

 

VS成员向导

在类视图中,显示了工程中定义的类及其成员

 

成员属性

 

类成员的其他议题


隐藏基类方法

当继承的成员并不是我们需要的时候,可以把它隐藏掉
例如:
public class MyBaseClass
{
   public void DoSomething()
   {
      //Base implementation
   }
}

public class MyDerivedClass:MyBaseClass
{
   public void DoSomething()
   {
      //Derived class implementation,hides base implementation
   }
}

这段代码隐藏了基类的DoSomething()方法,能正常运行,但会产生一个警告
如果用new关键字显式声明要隐藏的成员,就不会有警告
例如:
public class MyDerivedClass:MyBaseClass
{
   new public void DoSomething()
   {
      //Derived class implementation,hides base implementation
   }
}

注意隐藏和重写的区别
用override重写将会替换基类中的执行代码
而用隐藏的方式将会新建一个方法
即使要隐藏的方法虚拟的,该方法也不会被重写
主要的区别体现在多态中,被重写的成员将写入对象实例,而用于隐藏的代码将不会被写入
例如:
class MyBaseClass
{
    public virtual string DoSomething()
    {
        return "a";
    }
}

class MyDerivedClass1 : MyBaseClass
{
    public override string DoSomething()
    {
        return "b";
    }
}

class MyDerivedClass2 : MyBaseClass
{
    new public string DoSomething()
    {
        return "b";
    }
}

多态
MyBaseClass oA = new MyDerivedClass1();
MyBaseClass oB = new MyDerivedClass2();

结果:
oA.DoSomething()将返回"b",oB.DoSomething()将返回"a"


调用重写或隐藏的基类方法

无论重写成员还是隐藏成员,都可以在类的内部访问基类成员。
使用:
要对派生类隐藏基类的公共成员,但在类中访问其功能
要给继承的虚拟成员添加执行代码,而不只是重写

可以使用base关键字,它表示包含在派生类中的基类的执行代码
例如:
public class MyBaseClass
{
   public virtual void DoSomething()
   {
      //Base implementation
   }
}

public class MyDerivedClass:MyBaseClass
{
   public void DoSomething()
   {
      //code
      base.DoSomething();
      //code
   }
}
这里base.DoSomething()包含了基类中的DoSomething()方法的执行代码
base使用对象实例,所以在静态成员中使用

this关键字
与base相似,this也可以用在类成员的内部,也是引用对象实例
由this引用的对象实例是当前的对象实例


嵌套的类型定义

除了在名称空间中定义类之外,还可以在其他类中定义这些类
public class MyClass
{
   public class myNestedClass
   {
      public int nestedClassField;
   }
}

要在MyClass外部实例化myNestedClass:
MyClass.myNestedClass myObj = new MyClass.myNestedClass();

 

接口的执行

定义接口:
interface IMyInterface
{
   // Interface members.
}

接口成员:
1 所有接口成员都是公共的,不允许使用访问修饰符
2 接口成员不能包含代码体
3 接口不能定义域成员
4 接口成员不能使用关键字static, virtual, abstract, 或sealed来定义
5 接口不能定义成员类型

要隐藏继承了基接口的成员,可以用new关键字来定义
例如:
interface IMyBaseInterface
{
   void DoSomething();
}

interface IMyDerivedInterface : IMyBaseInterface
{
   new void DoSomething();
}

执行方式与隐藏继承的类成员一样

在接口中定义属性可以确定服务块get和set能否用于该属性
例如:
interface IMyInterface
{
   int MyInt
   {
   get;
   set;
   }
}

注意:接口没有指定属性应如何存储,接口不能指定域

接口与类一样可以定义为类的成员


在类中执行接口

执行接口的类必须包含该接口所有成员的执行代码,且必须匹配指定的签名,并且是公共的
可以使用关键字virtual或abstract来执行接口成员,但不能使用static或const

例如:
public interface IMyInterface
{
   void DoSomething();
   void DoSomethingElse();
}

public class MyClass : IMyInterface
{
   public void DoSomething()
   {
   }

   public void DoSomethingElse()
   {
   }
}

接口成员还可以在基类上执行
例如:
public interface IMyInterface
{
   void DoSomething();
   void DoSomethingElse();
}

public class MyBaseClass
{
   public void DoSomething()
   {
   }
}

public class MyDerivedClass : MyBaseClass, IMyInterface
{
   public void DoSomethingElse()
   {
   }
}

继承一个执行给定接口的基类,那么派生类隐式地支持这个接口
例如:
public interface IMyInterface
{
   void DoSomething();
   void DoSomethingElse();
}

public class MyBaseClass : IMyInterface
{
   public virtual void DoSomething()
   {
   }

   public virtual void DoSomethingElse()
   {
   }
}

public class MyDerivedClass : MyBaseClass
{
   public override void DoSomething()
   {
   }
}

注意:如果用隐藏而不是重写,则IMyInterface.DoSomething()将引用基类的方法,即使派生类通过这个接口来访问

显式执行接口成员

接口成员也可以由类显式执行
这时,该成员只能通过接口来访问,不能通过类来访问

例如:
public interface IMyInterface
{
   void DoSomething();
   void DoSomethingElse();
}

public class MyClass : IMyInterface
{
   void IMyInterface.DoSomething()
   {
   }

   public void DoSomethingElse()
   {
   }
}

其中DoSomething()是显式执行,DoSomethingElse()是隐式执行
对于显式执行的接口成员只能通过接口访问
例如:
IMyInterface myInt = new MyClass();
myInt.DoSomething();

对于隐式执行的接口成员可以通过类或接口来访问:
例如:
MyClass myObj = new MyClass();
myObj.DoSomething();
或者
IMyInterface myInt = new MyClass();
myInt.DoSomething(); 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值