第7篇 WPF C# 怎样定义类及其接口
1、概述
1.1 类和接口的本质
类和接口用于表述事物的特征,从而成为可编程的东西。也就是将物理存在的事物表述为编程可用的代码。
类提供一个好像标准模板一样的东西,通过实例化变成程序中各个不同的对象。
接口是不能实例化的与类一样的东西(定义语法不通)。
下图分析怎样将物理存在的事物概括为类或接口。
1.1.1 抽象类、派生类、接口、结构
比如车,就是一个抽象类。而汽车、火车也是抽象类。汽车中的轿车、SUV、客车就是具体的类。
汽车、火车是车的派生类。轿车、SUV、客车是汽车的派生类。
汽车的载客数量、轮胎型号、火车的载重是特征。
派生于不同的抽象类的派生类可能具有共同的特征,这些特征可定义为接口。
结构则是具体数值的类。
1.1.2 类的浅度复制和深度复制
简单地按照成员复制对象称为浅度复制,可通过派生于System.Object的MemberwiseClone()方法来完成。这是一个受保护的方法,但可以很容易在对象上定义一个调用该方法的公共方法。浅度复制未考虑“引用类型成员”,因此,新对象的“引用成员”就会指向 源对象中 相同成员 引用的 对象,这是浅度复制的局限。
如果要创建成员的新实例,复制值,而不复制引用,此时需要深度复制。可使用一个标准的方法来进行,即通过实现一个ICloneable接口来完成。如果使用ICloneable接口,必须实现它包含的Clone()方法,这个方法返回一个System.Object的值。我们可以采用各种处理方式,实现所选的任何一个方法得到这个对象。深度复制的局限是 该方法应该返回什么,并无规则和限制。
1.1.3 部分类的定义
1.1.4 部分方法的定义
1.2 编程设计:类库项目
定义类的代码可以放在不同的文件中,也可以放在不同的项目中。只包含类文件的项目称为类库项目。类库项目编译后生成.dll程序集文件。在不同的项目中使用类库内的类,通过引用该.dll程序集文件进行。引用后,在XAML前台标记文件中,应声明其命名空间;在代码隐藏文件(后台)中应使用Using语句声明。
2、类、接口、结构的定义标准语法
1.1 类的定义
1.1.1 声明类和接口
public class MyClass[ : MyBase][, IMyInterface][, IMySecondInterface]
{
// Class members.
}
1.1.2 定义构造函数和析构函数
定义构造函数
(1)默认构造函数:如未定义,则自动生成默认构造函数
(2)重构函数:可定义多个重构函数
(3)构造函数的执行顺序:总是从最基的类开始,执行前总是先调用函数
语法:
public MyClass()
{ public MyClass() { // Default constructor code. } public MyClass(int myInt) { // Nondefault constructor code (uses myInt). } }
定义析构函数
当进行垃圾回收时,就执行析构函数中的代码,释放资源。调用这个函数后,还会隐式地调用基类的析构函数,包括System.Object 根类(root class)中的Finalize() 调用。
语法:
class MyClass { ~MyClass() { // Destructor body. } }
1.1.3 定义类成员
一、使用代码定义类成员
(1)定义字段
标准语法
class MyClass { public [readonly] int MyInt = 17; }
(2)定义方法
定义方法使用标准函数、可访问性和可选的static修饰符完成。
举例:
class MyClass { public string GetString() //返回类型string
{
return "Here is a string.";
}
}
public class MyBaseClass
{
public virtual void DoSomething() //virtual-----方法可以重写
{
// Base implementation.
}
}
public class MyDerivedClass : MyBaseClass
{
public override void DoSomething()//override ---- 重写了一个基类的方法(如果重写方法,必须使用该关键字)
{
// Derived class implementation, overrides base implementation.
}
}
public class MyDerivedClass : MyBaseClass
{
public override sealed void DoSomething() //sealed----如果使用了重写,可以指定在派生类中不能对此方法重写。
{
// Derived class implementation, overrides base implementation.
}
}
(3)定义属性
采用基本结构
public int MyIntProp { get //访问器 { // Property get code. } set //访问器 { // Property set code. } }
举例
// Field used by property.
private int myInt; // Property. public int MyIntProp { get { return myInt; } set { // Property set code. } }
// Field used by property. private int myInt; // Property. public int MyIntProp { get { return myInt; } set { myInt = value; } }
采用自动生成的结构:
public int MyIntProp { get; set; }
可以书写为:
public int MyIntProp { get; set; }
二、使用类图添加成员和定义属性
(略)
三、怎样正确定义类成员
a、使用恰当的关键字
定义类和成员字段的关键字如下:
➤ public — Members are accessible from any code.
➤ private — Members are accessible only from code that is part of the class (the default if no keyword is used).
➤ internal — Members are accessible only from code within the assembly (project) where they are defi ned.
➤ protected — Members are accessible only from code that is part of either the class or a derived class.
定义字段还可以使用readonly关键字。
定义方法的关键字如下:
➤ static — The method is accessible only through the class, not the object instance.必须通过类访问,不能通过对象实例访问。
➤ virtual — The method can be overridden.该方法可以被重写。
➤ abstract — The method must be overridden in non-abstract derived classes (only permitted in abstract classes).该方法仅可在非抽象的派生类中重写。
➤ override — The method overrides a base class method (it must be used if a method is being overridden).重写了一个基类的方法(如果重写方法,必须使用该关键字)
➤ override sealed — 指定在派生类中不能对此方法重写
➤ extern — The method definition is found elsewhere.方法在其它地方定义。
定义属性的关键字如下:
可以使用virtual, override, and abstract
b、使用自动属性和外部只读属性
使用自动属性只能通过属性访问,不能通过底层的私有字段访问。无法使用自动属性定义只读或只写的属性,但可以创建一个外部只读属性,如下代码所示:
public int MyIntProp { get; private set; }
Here you can access the value of MyIntProp only from code in the class defi nition.
c、隐藏基类方法
例如,当继承的公共成员不像预期那样工作时,就可以隐藏基类。
c1、举例如下:
public class MyBaseClass//基类 { public void DoSomething() { // Base implementation
}
}
public class MyDerivedClass : MyBaseClass //继承基类的类
{
public void DoSomething()
{
// Derived class implementation, hides base implementation.
}
}
上述代码编译时会发出警告。如果确系需要隐藏,纠正的方法如下:
public class MyDerivedClass : MyBaseClass { new public void DoSomething() { // Derived class implementation, hides base implementation. } }
c2、通过重写方法实现新的方法,举例如下:
public class MyBaseClass { public virtual void DoSomething() { Console.WriteLine("Base imp"); } } public class MyDerivedClass : MyBaseClass { public override void DoSomething() { Console.WriteLine("Derived imp"); } }
c3、c2可以书写为:
public class MyBaseClass { public virtual void DoSomething() { Console.WriteLine("Base imp"); } } public class MyDerivedClass : MyBaseClass { new public void DoSomething() { Console.WriteLine("Derived imp"); } }
d、调用重写或隐藏的基类的方法
d1、base关键字
d2、this关键字
e、嵌套的类型定义
2.2 接口的实现
including a call to
in the System.Object root class. This