对象、类、结构

来源:互联网 发布:网络鬼畜是什么意思 编辑:程序博客网 时间:2024/05/16 18:08

对象
    对象是具有数据、行为和标识的编程结构。对象数据包含在对象的字段、属性和事件中,对象行为则由对象的方法和接口定义。
    对象具有标识 -- 数据集相同的两个对象不一定是同一对象。
    C# 中的对象通过 classesstructs 定义 -- 该类型的所有对象都按照它们构成的同一蓝图操作。
    对象具有以下特点:
    1、 C# 中使用的全都是对象,包括 Windows 窗体和控件。
    2、 对象是实例化的;也就是说,对象是从类和结构所定义的模板中创建的。
    3、 对象使用属性(C# 编程指南)获取和更改它们所包含的信息。
    4、 对象通常具有允许它们执行操作的方法和事件。
    5、 所有 C# 对象都继承自 Object。


    类是 C# 中功能最为强大的数据类型。像结构一样,类也定义了数据类型的数据和行为。然后,程序员可以创建作为此类的实例的对象。与结构不同,类支持继承,而继承是面向对象编程的基础部分。
类是使用 class 关键字来定义的,如下面的示例所示:
public class Customer
{
    //Fields, properties, methods and events go here...
}
    class 关键字前面是访问级别。在该例中,使用了 public,这表示任何人都可以基于该类创建对象。类的名称位于 class 关键字的后面。定义的其余部分是类的主体,用于定义行为和数据。类的字段、属性、方法和事件统称为“类成员”。

    创建对象
    尽管有时类和对象可互换,但它们是不同的概念。类定义对象的类型,但它不是对象本身。对象是基于类的具体实体,有时称为类的实例。
    通过使用 new 关键字,后跟对象将基于的类的名称,可以创建对象,如下所示:
    Customer object1 = new Customer();
    创建类的实例后,将向程序员传递回对该对象的引用。在上例中,object1 是对基于 Customer 的对象的引用。此引用引用新对象,但不包含对象数据本身。实际上,可以在根本不创建对象的情况下创建对象引用:
    Customer object2;
    建议不要创建像这样的不引用对象的对象引用,因为在运行时通过这样的引用来访问对象的尝试将会失败。但是,可以创建这样的引用来引用对象,方法是创建新对象,或者将它分配给现有的对象,如下所示:
Customer object3 = new Customer();
Customer object4 = object3;
    此代码创建了两个对象引用,它们引用同一个对象。因此,通过 object3 对对象所做的任何更改都将反映在随后使用的 object4 中。这是因为基于类的对象是按引用来引用的,因此类称为引用类型。

    类继承
    继承是通过使用派生来实现的,而派生意味着类是使用基类声明的,它的数据和行为从基类继承。通过在派生的类名后面追加冒号和基类名称,可以指定基类,如下所示:
public class Manager : Employee
{
    // Employee fields, properties, methods and events are inherited
    // New Manager fields, properties, methods and events go here...
}
当类声明基类时,为基类定义的所有类成员也成为新类的一部分。因为基类自身可能继承自另一个类,而后者又从另一个类继承,依此类推,最终类可能具有很多个基类。
public class Person
{
    // Field
    public string name;

    // Constructor
    public Person()
    {
        ;
    }

    // Method
    public void SetName(string newName)
    {
        >    }
}
class TestPerson
{
    static void Main()
    {
        Person person1 = new Person();
        System.Console.WriteLine(person1.name);

        person1.SetName("John Smith");
        System.Console.WriteLine(person1.name);
    }
}
输出
unknown
John Smith

结构
    结构是使用 struct 关键字定义的,例如:
public struct PostalAddress
{
    // Fields, properties, methods and events go here...
}
尽管结构的静态字段可以初始化,结构实例字段声明还是不能使用初始值设定项。
结构不能声明默认构造函数(没有参数的构造函数)或析构函数。
    结构的副本由编译器自动创建和销毁,因此不需要使用默认构造函数和析构函数。实际上,编译器通过为所有字段赋予默认值(参见默认值表)来实现默认构造函数。结构不能从类或其他结构继承。
    结构是值类型 -- 如果从结构创建一个对象并将该对象赋给某个变量,变量则包含结构的全部值。复制包含结构的变量时,将复制所有数据,对新副本所做的任何修改都不会改变旧副本的数据。由于结构不使用引用,因此结构没有标识 -- 具有相同数据的两个值类型实例是无法区分的。C# 中的所有值类型本质上都继承自 ValueType,后者继承自 Object。
结构具有以下特点:
    结构是值类型,而类是引用类型。
    向方法传递结构时,结构是通过传值方式传递的,而不是作为引用传递的。
    与类不同,结构的实例化可以不使用 new 运算符。
    结构可以声明构造函数,但它们必须带参数。
    一个结构不能从另一个结构或类继承,而且不能作为一个类的基。所有结构都直接继承自 System.ValueType,后者继承自System.Object
    结构可以实现接口。
    在结构中初始化实例字段是错误的。
public struct CoOrds
{
    public int x, y;

    public CoOrds(int p1,int p2)
    {
        x = p1;
        y = p2;
    }
}
    声明结构的默认(无参数)构造函数是错误的。总是提供默认构造函数以将结构成员初始化为它们的默认值。在结构中初始化实例字段也是错误的。
    如果使用 new 运算符创建结构对象,则会创建该结构对象,并调用适当的构造函数。与类不同,结构的实例化可以不使用 new 运算符。如果不使用new,则在初始化所有字段之前,字段都保持未赋值状态且对象不可用。
    对于结构,不像类那样存在继承。一个结构不能从另一个结构或类继承,而且不能作为一个类的基。但是,结构从基类 Object 继承。结构可实现接口,其方式同类完全一样。
下面的示例演示使用默认构造函数和参数化构造函数的 struct 初始化:
public struct CoOrds
{
    public int x, y;

    public CoOrds(int p1,int p2)
    {
        x = p1;
        y = p2;
    }
}

// Declare and initialize struct objects.

class TestCoOrds
{
    static void Main()
    {
        // Initialize:  
        CoOrds coords1 = new CoOrds();
        CoOrds coords2 = new CoOrds(10, 10);

        // Display results:
        System.Console.Write("CoOrds 1: ");
        System.Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);

        System.Console.Write("CoOrds 2: ");
        System.Console.WriteLine("x = {0}, y = {1}", coords2.x, coords2.y);
    }
}
输出
CoOrds 1: x = 0, y = 0
CoOrds 2: x = 10, y = 10
下面举例说明了结构特有的一种功能。它在不使用 new 运算符的情况下创建 CoOrds 对象。如果将 struct 换成class,程序将不会编译。
public struct CoOrds
{
    public int x, y;

    public CoOrds(int p1,int p2)
    {
        x = p1;
        y = p2;
    }
}

// Declare a struct object without "new."

class TestCoOrdsNoNew
{
    static void Main()
    {
        //

        // Initialize:
        coords1.x = 10;
        coords1.y = 20;

        // Display results:
        System.Console.Write("CoOrds 1: ");
        System.Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);
    }
}
输出
CoOrds 1: x = 10, y = 20

继承
    类可以从其他类中继承。这是通过以下方式实现的:在声明类时,在类名称后放置一个冒号,然后在冒号后指定要从中继承的类(即基类)。例如:
public class A
{
    public A() { }
}
public class B : A{public B() { }
}
新类(即派生类)将获取基类的所有非私有数据和行为以及新类为自己定义的所有其他数据或行为。因此,新类具有两个有效类型:新类的类型和它继承的类的类型。
    使用 abstract 关键字可以创建仅用于继承用途的类和类成员,即定义派生的非抽象类的功能。使用sealed 关键字可以防止继承以前标记为 virtual 的类或某些类成员。
可以将类声明为抽象类。方法是在类定义中将关键字 abstract 置于关键字 class 的前面。例如:
public abstract class A
{
    // Class members here.
}
    抽象类不能实例化。抽象类的用途是提供多个派生类可共享的基类的公共定义。例如,类库可以定义一个作为其多个函数的参数的抽象类,并要求程序员使用该库通过创建派生类来提供自己的类实现。
    抽象类也可以定义抽象方法。方法是将关键字 abstract 添加到方法的返回类型的前面。例如:
public abstract class A
{
    public abstract void DoWork(int i);
}
    抽象方法没有实现,所以方法定义后面是分号,而不是常规的方法块。抽象类的派生类必须实现所有抽象方法。当抽象类从基类继承虚方法时,抽象类可以使用抽象方法重写该虚方法。例如:
// compile with: /target:library
public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}
public abstract class E : D
{
    public abstract override void DoWork(int i);
}
public class F : E
{
    public override void DoWork(int i)
    {
        // New implementation.
    }
}
   如果将虚方法声明为抽象方法,则它对于从抽象类继承的所有类而言仍然是虚的。继承抽象方法的类无法访问该方法的原始实现。在前面的示例中,类 F 上的 DoWork 无法调用类 D 上的DoWork。在此情况下,抽象类可以强制派生类为虚方法提供新的方法实现。
    可以将类声明为密封类。方法是在类定义中将关键字 sealed 置于关键字class 的前面。例如:
public sealed class D{// Class members here. }
    密封类不能用作基类。因此,它也不能是抽象类。密封类主要用于防止派生。由于密封类从不用作基类,所以有些运行时优化可以使对密封类成员的调用略快。
    在对基类的虚成员进行重写的派

原创粉丝点击