C#(十六)之C#类中的成员属性 构造函数 析构函数

简介: 本篇内容记录了成员属性、构造函数、析构函数的一些基本用法。

QQ图片20220426110546.jpg

C#中类的成员属性、构造函数、析构函数。


代码是基于昨天类的代码进行测试的。


一、基本代码:


/*声明对象*/
cat Tom = new cat();
Tom.age = -1;  //设置年龄
Tom.TalkAge();  //输出:我今年-1岁了


二、类中的方法:


/*我今年几岁了*/
public void TalkAge()
{
     Console.WriteLine("我今年{0}岁了",age);
}


这个代码是没有问题的,但是逻辑有问题,没有人可能是-1岁。

那么可以定义一个访问器进行数据合法性的检查。


这样做的好处就是即检查了数据的合法性,又加强了类的封装


上代码:


类中的代码:


private int age;
private int miceCount = 0;// 私有的
        /*访问器 start*/
        public void TellAge(int getAge)
        {
            if (getAge < 0)
            {
                age = 0;
            }
            else {
                age = getAge;
            }
        }
        public int PutAge()
        {
            return age;
        }
        /*访问器 end*/


调用:


Tom.TellAge(3);
int age = Tom.PutAge();
Console.WriteLine("我今年{0}岁了", age);  //输出我今年3岁了
// 输出负数是什么效果,可以自己尝试下。


C#中这样写是没有问题的,但是C#提供了一个更好的解决方法:属性


三、定义属性:


private int age;       
        // 定义一个属性
        public int Age
        {
            get{ // 返回值
                return age;
            }
            set{ //赋值
                if(value > 0){
                    age = value;
                }else{
                    age = 0;
                }
            }
        }
// value 关键字就是赋给变量的值
// 调用属性
            Tom.Age = -1;
            Console.WriteLine("我今年{0}岁了",Tom.Age);  //输出:我今年0岁了


四、接下来看下C#类中的构造函数:


1:默认构造函数:


就是我们在使用类的时候实例化的函数:


/*声明对象*/
cat Tom = new cat();


然后再对类中声明的共有属性进行赋值。


2:带参数的构造函数:


如果类型声明的变量都是私有的,我们可以通过构造函数给其赋值。


构造函数名称必须与类名称相同


类:


/*声明构造函数*/
        public cat(string putname,int putage)
        {
            age = putage;
            name = putname;
            Console.WriteLine("我叫{0},今年{1}岁了",name,age);
            // 输出:我叫gc,今年23岁了
        }


调用:


/*声明对象*/
cat Tom = new cat("gc",23);


3:无参构造函数


说白了就是把有参构造函数里边的参数给去了就行了。


/*声明构造函数*/
        public cat()
        {
            age = 0;
            name =’’;
            Console.WriteLine("我叫{0},今年{1}岁了",name,age);
            // 输出:我叫gc,今年23岁了
        }


调用:


/*声明对象*/
cat Tom = new cat();


析构函数:


作用:删除或者释放掉不使用的对象来释放内存空间。


析构函数的定义:


/*析构函数*/
~cat() {
      Console.WriteLine("我走了");
}


C#程序中在创建类的时候默认定义了一个构造函数与析构函数,所以,没有特殊需要,不需要二次定义。


析构函数让我定义在了构造函数下边,那我在析构函数下边定义一个类,看其是否可以访问到。


//在类中添加了析构函数
            cat Tom = new cat();
            //输出:
            /*
             我来了
             我走了
             */
            // 析构函数让我定义在了构造函数下边,那我在析构函数下边定义一个类,看其是否可以访问到。
            for (int i = 0; i < 5; i++)
            {
                Tom.CatchMouse();
                /*
                输出:
                我来了
                我抓了1只老鼠
                我抓了2只老鼠
                我抓了3只老鼠
                我抓了4只老鼠
                我抓了5只老鼠
                我走了
                 */
            }
            // 析构函数是在函数调用之后再执行的,与其放置的位置没有关系。


析构函数用处不大,知道就好。


测试所用代码:


类文件:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace gc
{
    class cat
    {
        public string name;       // 共有的
        private int age;
        private int miceCount = 0;// 私有的
        /*声明无参构造函数*/
        public cat()
        {
            age = 0;
            name = "";
            Console.WriteLine("我来了");
        }
        /*析构函数*/
        ~cat() {
            Console.WriteLine("我走了");
        }
        /*声明有参构造函数*/
        /*public cat(string putname,int putage)
        {
            age = putage;
            name = putname;
            Console.WriteLine("我叫{0},今年{1}岁了",name,age);
            // 输出:我叫gc,今年23岁了
        }//*/
        // 定义一个属性
        public int Age
        {
            get{ // 返回值
                return age;
            }
            set{ //赋值
                if(value > 0){
                    age = value;
                }else{
                    age = 0;
                }
            }
        }
        /*访问器 start*/
        public void TellAge(int getAge)
        {
            if (getAge < 0)
            {
                age = 0;
            }
            else {
                age = getAge;
            }
        }
        public int PutAge()
        {
            return age;
        }
        /*访问器 end*/
        /*我今年几岁了*/
        public void TalkAge()
        {
            Console.WriteLine("我今年{0}岁了", age);
        }
        /*私有行为*/
        private void Hello()
        {
            Console.WriteLine("只有我自己能用");
        }
        /*公共行为*/
        public void Method()
        {
            Hello();
            Console.WriteLine("别人可以调用我");
        }
        /*捉老鼠*/
        public void CatchMouse()
        {
            miceCount++;
            //Hello();
            Console.WriteLine("我抓了{0}只老鼠", miceCount);
        }
    }
}


主文件:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using gc; //使用自己定义类的命名空间
namespace gc
{
    class Program
    {
        /* C#主要的运行函数,就是main函数 */
        static void Main(string[] args)
        {
            /*声明对象*/
            /*cat Tom = new cat();
            //Tom.name = "Tom"; // 设置姓名
            //Tom.age = -1;  //设置年龄
            //Tom.TalkAge();  //输出:我今年-1岁了
            Tom.TellAge(3);
            int age = Tom.PutAge();
            //Console.WriteLine("我今年{0}岁了", age);  //输出我今年3岁了
            // 输出负数是什么效果,可以自己尝试下。
            // 调用属性
            Tom.Age = -1;
            //Console.WriteLine("我今年{0}岁了",Tom.Age);  //输出:我今年0岁了//*/
            //在类中添加了析构函数
            cat Tom = new cat();
            //输出:
            /*
             我来了
             我走了
             */
            // 析构函数让我定义在了构造函数下边,那我在析构函数下边定义一个类,看其是否可以访问到。
            for (int i = 0; i < 5; i++)
            {
                Tom.CatchMouse();
                /*
                输出:
                我来了
                我抓了1只老鼠
                我抓了2只老鼠
                我抓了3只老鼠
                我抓了4只老鼠
                我抓了5只老鼠
                我走了
                 */
            }
            // 析构函数是在函数调用之后再执行的,与其放置的位置没有关系。
        }
    }
}




目录
相关文章
|
3月前
|
开发框架 .NET C#
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
【10月更文挑战第9天】在 C#/.NET Core 中,有多种方法可以删除字符串的最后一个字符,包括使用 `Substring` 方法、`Remove` 方法、`ToCharArray` 与 `Array.Copy`、`StringBuilder`、正则表达式、循环遍历字符数组以及使用 LINQ 的 `SkipLast` 方法。
|
4月前
|
存储 C# 索引
C# 一分钟浅谈:数组与集合类的基本操作
【9月更文挑战第1天】本文详细介绍了C#中数组和集合类的基本操作,包括创建、访问、遍历及常见问题的解决方法。数组适用于固定长度的数据存储,而集合类如`List<T>`则提供了动态扩展的能力。文章通过示例代码展示了如何处理索引越界、数组长度不可变及集合容量不足等问题,并提供了解决方案。掌握这些基础知识可使程序更加高效和清晰。
98 2
|
22天前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
77 12
|
4月前
|
安全 C# 索引
C#一分钟浅谈:属性与索引器的定义
本文深入浅出地介绍了C#编程中的属性和索引器。属性让字段更安全,通过访问器方法在读写时执行额外操作,如验证数据有效性;索引器则赋予类数组般的访问方式,支持基于索引的数据访问模式。文章通过示例代码展示了如何定义及使用这两种特性,并提供了常见问题及其解决方案,帮助读者写出更健壮、易维护的代码。希望读者能从中学习到如何有效利用属性和索引器增强C#类的功能性。
120 12
|
3月前
|
Java 程序员 C#
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
18 0
|
4月前
|
C# 数据安全/隐私保护
C# 一分钟浅谈:类与对象的概念理解
【9月更文挑战第2天】本文从零开始详细介绍了C#中的类与对象概念。类作为一种自定义数据类型,定义了对象的属性和方法;对象则是类的实例,拥有独立的状态。通过具体代码示例,如定义 `Person` 类及其实例化过程,帮助读者更好地理解和应用这两个核心概念。此外,还总结了常见的问题及解决方法,为编写高质量的面向对象程序奠定基础。
39 2
|
5月前
|
Java C# 索引
C# 面向对象编程(一)——类
C# 面向对象编程(一)——类
43 0
|
5月前
|
开发框架 .NET 编译器
C# 中的记录(record)类型和类(class)类型对比总结
C# 中的记录(record)类型和类(class)类型对比总结
|
2月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
44 3
|
2月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
79 4