首页 / 教程列表 / C#程序设计基础(入门篇) / 面向对象编程(类和对象)

面向对象编程(类和对象)

2507 1 评论 更新于: 2021-08-27 读完约需 8 分钟

内容提要

本文你将学习到:

  • 什么是对象(Object)
  • 什么是类(Class)
  • 如何定义一个类
  • 类的成员(方法,属性,字段等)

概述

在此之前,我们学习的基本都是C#编程的最基础知识,如果把学习C#语言类比学习中文的话,目前这个阶段相当于我们刚学习完汉语拼音和汉字。那么如何将这些汉字结合起来组成句子,对应C#编程中如何使用这些C#基础知识来编写程序,就需要我们继续探索和学习熟练掌握C#语言更丰富的知识。

从本节起,我们将进入C#语言的面向对象编程(OOP:Object-Oriented Programming)部分的学习。面向对象编程也是C#编程的核心思想,熟悉并掌握C#的面向对象编程,才算真正打开C#程序设计的大门。

之前我们写示例代码的时候,所有的功能代码都被写在了Program.cs这个文件中,这是一种面向过程的编程方式。

当程序功能较少的时候不会暴露什么问题,但当程序功能越来越多的时候,面向过程编程将是一个灾难,这种方式编写出来的代码极难阅读,极不方便维护和扩展,也没有模块化,代码的复用性不高。而面对对象编程正是为解决这些问题而设计的。

对象

现实世界中的实体统称为对象(世间万物皆对象),比如有生命的(人,动物)或者无生命的(车,房,电脑,智能手机,平板等等),具体的(书,电视)或者抽象的(税率,条例等)。

对象有两个特征:属性和行为。比如房子(House)可能有以下的属性:

  • 门牌号(House Number)
  • 业主(Owner)
  • 房间数(Number of Rooms)
  • 面积(Area)
  • 室内温度(Temperature)
  • 修建年份(Year)
  • 购买价格(Buying Price)

有以下的行为(方法):

  • 开门(Open Door)
  • 关门(Close Door)
  • 安装空调(Install Air Conditioner)
  • 测量室内温度(Measure Indoor Temperature)

或者一只狗有这些属性:颜色,年龄,体重,类型等等,它有的行为:吠,吃,跑,嗅等。
在C#语言中,以上的房子或者狗的属性我们称之为字段或者属性(fields/properties),而行为被称之为方法(methods)。这些字段/属性/方法又统称类的成员

在一个类中,字段/属性/方法这些类的成员都是可选的,也就是说一个类中可以没有字段、属性、方法,即一个空类。

那么如何将实现世界中的对象与C#程序语言结合起来呢,这里就该我们的”类”出场了。

示例演示为什么要使用类和对象

看来看一个不使用类和对象定义若干个房子的实例代码:

// House 1
string houseNumber1;
string houseOwner1;
float houseArea1;

// House 2
string houseNumber2;
string houseOwner2;
float houseArea2;

// House 3
string houseNumber3;
string houseOwner3;
float houseArea3;

以上示例代码中,基于之前学习过的变量的相关知识,我们使用不同的变量来描述不同房子的不同属性。

比如房子的房号,这里有3个房子,我们就需要分别定义3个不同的房号变量:house1HouseNumber。类似的,我们还分别用不同变量来定义的房子的户主、面积属性。

想一想,如果再有几个房子,我们怎么来维护这些属性信息呢?

类是具有相似属性和方法的对象的集合(是用于创建相同类型的对象的模板)。

类的语法结构:

[access modifier] class className
{
    //类的成员
    [class body]
}

在C#语言中,还有与类相似声明的类型,如结构(struct)和记录(record)。其中结构是值类型的数据类型,记录是C# 9中引入的引用类型的数据类型,它是一种为处理数据模型提供特殊的语法和行为的类。在声明结构和记录时,请分别使用关键字structrecord。关于结构和记录,将在专门的章节进行介绍。

还是拿Program.cs这个文件来举例,对应类的书写语法:

class Program
{
    static void Main(string[] arguments)
    {

    }
}

类的成员

成员分类:

  • 字段
  • 属性
  • 方法
  • 索引
  • 委托
  • 事件
  • 嵌套类

以下是定义一个类的语法结构:

[access modifier] class className
{
    #region 类的成员
    // 成员-变量
    [access specifier] <data type> variable1;
    [access specifier] <data type> variable2;
    ...
    [access specifier] <data type> variableN;

    // 成员-属性
    [access specifier] <data type> <property1> {get;set;}
    [access specifier] <data type> <property2> {get;set;}
    ...
    [access specifier] <data type> <propertyN> {get;set;}

    // 成员-方法
    [access specifier] <return type> method1(parameter_list) {
        // 方法体
    }
    [access specifier] <return type> method2(parameter_list) {
        // 方法体
    }
    ...
    [access specifier] <return type> methodN(parameter_list) {
        // 方法体
    }
    #endregion
}

现在我们还是以上面的房子作为示例,来演示在C#语言编程中是如何用类描述现实生活中的实际对象的。

以上面提到的房子(House)属性和方法为例,新建一个House类:

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {

        }
    }

    class House
    {
        public string HouseNumber { get; set; }
        public string Owner { get; set; }
        public float Area { get; set; }
    }
}

为了示例方便,直接将House类与Program类放在了同一个文件中。但在正式的项目开发中,建议用单独的类文件来存放专门的类。比如,这里我们可以单独创建一个名为House.cs的文件,如下图:

新建类的具体步骤如下:

1.打开添加新项窗口

2.添加新项

类的使用(实例化对象)

上面我们创建了一个类(House),那么,我们应该如何使用这个类呢?

与之前学习过的变量声明方式相同,我们只需在使用的地方声明一个类型为House的变量即可,如下:

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            House house;
        }
    }
}

以上示例代码中声明了一个类型为House的变量house,但并未对其进行赋值,同时我们还未使用这个变量进行其他操作,所以,Visual Studio编译器被提示如下信息:

声明了变量”house”,但从未使用过

C#语言中被定义为类的类型是引用类型。要将类实例化成一个实例对象,需要使用关键字new,一个只声明但未实例化的引用类型变量的默认值为null。接下来,我们就用new关键字来实例化一个House对象,示例代码如下:

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            House house;
            house = new House();
        }
    }
}

语句house = new House();即是实例化一个House对象。如果你觉得有些不好理解,那我们把House这个类比作设计师设计房子模型。new House()就相当于建筑师按照设计模型用钢筋混凝土修了一个真正的房子,这就叫类的实例化

在C#语言中,类的实例化得到的称之为对象

House house; // house(我的房子) is null

// 使用new关键字实例化一个对象
// 创建对象时,在托管堆上为这个对象分配足够的内存空间,并将变量指向该对象在内存地址的引用。
// 好比:我是一名建筑设计师,手上有一张设计好的房子的设计图(House类),现在委托建筑师帮我修建(new House())。当建筑工程师按照设计把房子建好之后,告诉我这个房子的地址,我将房子的地址保存在一张小卡片(house)上。
// 这里的house对应小卡片,它是房子的引用地址(给房子做一个标签,标注这个房子是谁家的)
// 当我们需要用这个房子的时候,我根据这个标签就能找到。
house = new House();

现在,我们得到了一个房子(House)的实例,心急的你是否在想如何访问这个实例的属性,比如房号(HouseNumber)呢?

C#语言中,访问对象的成员语法如下:

  • 访问属性:[变量名.属性名]
  • 访问字段:[变量名.字段名]
  • 访问方法:[变量名.方法名()]

如果你现在通实例house来访问房号(HouseNumber),控制台将不会有任何输出,如下:

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            House house;
            house = new House();
            Console.WriteLine(house.HouseNumber);
            Console.ReadKey();
        }
    }
}

因为我们还未设置house对象的属性值。那么,我们就来看看实例对象是如何赋值的。对可以访问的对象属性也是使用等号(=)进行赋值的,示例代码如下:

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            House house;
            house = new House();
            house.HouseNumber = "302";
            house.Area = 120;
            house.Owner = "张先生";
            Console.WriteLine($"房号:{house.HouseNumber}");
            Console.WriteLine($"户主:{house.Owner}
        }
    }
}

以上示例代码中,我们分别对房子的房号(HouseNumber)、面积(Area)、户主(Owner)进行了赋值,使用的语法是[变量名.属性名]=值的方式。

类的成员的可访问性与定义时的访问修饰符有关,这里请我们全部设置成了public。关于访问修饰符将在后续章节作详细介绍,这里只作了解。

运行结果如下:

房号:302
户主:张先生
面积:120

回到本节最开始使用不同变量定义不同房子的场景:houseNumber1houseNumber2houseNumber3,再对比类的特性,我们尝试用类来定义不同的房子,应该如何实现呢?

示例代码如下:

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            House house1;
            house1 = new House();
            house1.HouseNumber = "302";
            house1.Area = 120;
            house1.Owner = "张先生";

            House house2;
            house2 = new House();
            house2.HouseNumber = "503";
            house2.Area = 90;
            house2.Owner = "李先生";

            House house3;
            house3 = new House();
            house3.HouseNumber = "606";
            house3.Area = 150;
            house3.Owner = "刘先生";
        }
    }
}

怎么样,使用类来管理和维护,代码看起来是否要整洁得多呢?

再结合我们之前已经学到的《C#隐式类型变量》以及C#的对象初始化器,可以将上面的代码简化成如下所示:

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var house1 = new House { HouseNumber = "302", Area = 120, Owner = "张先生" };
            var house2 = new House { HouseNumber = "503", Area = 90, Owner = "李先生" };
            var house3 = new House { HouseNumber = "606", Area = 150, Owner = "刘先生" };
        }
    }
}

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

发表评论

登录用户才能发表评论, 请 登 录 或者 注册

热门评论(1)

风古右 (2023-05-25)

大道至简,取其精华去其糟粕

  • 感谢你的支持和反馈!

    Rector · 2023-09-08