P24 什么是类

从本节开始深入学习面向对象编程。

当前的视频教程是 1.0 版本,针对的是 C# 5.0。

1 前 22 讲的简要总结

  1. 讲解了 C# 基本元素、基本语法
  2. 把类的成员过了一遍:字段、属性、方法、事件
  3. 在前面其实已经讲过了封装、后面讲继承和多态

2 什么是“类”

类是一种数据结构,它可以包含数据成员(常量和字段)、函数成员(方法、属性、事件、索引器、运算符、实例构造函数、静态构造函数和析构函数)以及嵌套类型。类类型支持继承,继承是一种机制,它使派生类可以对基类进行扩展和专用化。 —— 《C# 语言规范》

注:这是在描述类是什么,讲的是类的外延而不是类的内涵。

计算机领域的类有下面三个方面

  • 是一种数据结构(data structure)
  • 是一种数据类型
  • 代表现实世界中的"种类"

2.1 类是一种数据结构(Data Structure)

类是一种“抽象”的数据结构。

  • 类本身就是“抽象”的结果,例如把学生抽象为 Student 类;

  • 类也是“抽象”结果的载体。Student 类承载着学生的抽象(学生的 ID,学生的行为等)

这里提到的 data structure 和算法里面的 data structure 略有不同。算法里面的数据结构更多是指集合(List、Dictionary 等)数据类型。

namespace HelloClass
{
    class Program
    {
        static void Main(string[] args)
        {
            //Student stu = new Student();使用默认构造器
            Student stu = new Student(1,"Timonty") ;//自定义构造器,一旦使用自定义构造器,则默认构造器无效

            //类是实例的模板
            Console.WriteLine(stu.ID);
            Console.WriteLine(stu.Name);
            stu.Report();
        }
    }

    //1、类是一种数据结构
    //2、类是一种自定义的引用类型
    class Student
    {
        //自定义构造器
        public Student(int id,string name)
        {
            ID = id;
            Name = name;
        }

        //从现实世界学生抽象出来的属性
        public int ID { get; set; }
        public string Name { get; set; }

        //从现实世界学生抽象出来的行为
        public void Report()
        {
            Console.WriteLine($"I'm #{ID} student,my name is {Name}.");
        }
    }
}

2.2 类是一种数据类型

类是一种引用类型,具体到每一个类都是一个自定义的类型:

  1. 可以用类去声明变量
  2. 可以用类去创建实例(把类作为实例的模板)

反射与 dynamic 示例

这两个示例也展现了类作为“数据类型”的一面。

反射的基础:

            Type t = typeof(Student);
            object o = Activator.CreateInstance(t, 1, "Timothy");
            Student stu = o as Student;
            Console.WriteLine(stu.Name);

dynamic 编程:

            Type t = typeof(Student);
            dynamic stu = Activator.CreateInstance(t, 1, "Timothy");
            Console.WriteLine(stu.Name);

 

2.3 代表现实世界中的“种类”

程序中的类与哲学、数学中的类有相通的地方。

namespace HelloClass
{
    class Program
    {
        static void Main(string[] args)
        {
            Student s1 = new Student(1, "Timothy");
            Student s2 = new Student(2, "Jacky");
            Console.WriteLine(Student.Amount);
        }
    }

    //1、类是一种数据结构
    //2、类是一种自定义的引用类型
    class Student
    {
        public static int Amount { get; set; }

        static Student()//静态构造器
        {
            Amount = 100;

        }

        //自定义构造器
        public Student(int id,string name)
        {
            ID = id;
            Name = name;
            Amount++;
        }

        //自定义析构器
        ~ Student()
        {
            Console.WriteLine("Bye bye! Release the system resources..");
        }

        //从现实世界学生抽象出来的属性
        public int ID { get; set; }
        public string Name { get; set; }

        //从现实世界学生抽象出来的行为
        public void Report()
        {
            Console.WriteLine($"I'm #{ID} student,my name is {Name}.");
        }
    }
}

3 构造器与析构器

namespace HelloClass
{
    class Program
    {
        static void Main(string[] args)
        {
            //Student stu = new Student();使用默认构造器
            Student stu = new Student(1,"Timonty") ;//自定义构造器,一旦使用自定义构造器,则默认构造器无效

            //类是实例的模板
            Console.WriteLine(stu.ID);
            Console.WriteLine(stu.Name);
            stu.Report();
        }
    }

    //1、类是一种数据结构
    //2、类是一种自定义的引用类型
    class Student
    {
        //自定义构造器
        public Student(int id,string name)
        {
            ID = id;
            Name = name;
        }

        //自定义析构器
        ~ Student()
        {
            Console.WriteLine("Bye bye! Release the system resources..");
        }

        //从现实世界学生抽象出来的属性
        public int ID { get; set; }
        public string Name { get; set; }

        //从现实世界学生抽象出来的行为
        public void Report()
        {
            Console.WriteLine($"I'm #{ID} student,my name is {Name}.");
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在上一题Point2D和Point3D的基础上,新建一个TestPointV2,在TestPointV2的main()方法中添加如下语句。 Scanner sc = new Scanner(System.in); System.out.println("Please enter the coordinates of p23:"); double p23x = sc.nextDouble(); double p23y = sc.nextDouble(); Point2D p23 = new Point2D(p23x, p23y); System.out.println("Please enter the coordinates of p31:"); double p31x = sc.nextDouble(); double p31y = sc.nextDouble(); double p31z = sc.nextDouble(); Point3D p33 = new Point3D(p31x, p31y, p31z); System.out.println("Please enter the coordinates of p24:"); double p24x = sc.nextDouble(); double p24y = sc.nextDouble(); double p24z = sc.nextDouble(); sc.close(); // The reference of the parent class refers to the object of the subclass. Point2D p24 = new Point3D(p24x, p24y, p24z); System.out.println("Does " + p23 + " coincide with " + p33 + "? -- "+ p23.equals(p33)); System.out.println("Does " + p33 + " coincide with " + p23 + "? -- "+ p33.equals(p23)); System.out.println("Does " + p33 + " coincide with " + p24 + "? -- "+ p33.equals(p24)); System.out.println("Does " + p24 + " coincide with " + p33 + "? -- "+ p24.equals(p33)); System.out.println("Does " + p23 + " coincide with " + p24 + "? -- "+ p23.equals(p24)); System.out.println("Does " + p24 + " coincide with " + p23 + "? -- "+ p24.equals(p23)); 假设引用变量p23、p33和p24所指点对象的坐标依次为(0, 0),(0, 0, 5),(0, 0, 5)。从键盘输入这三个点的坐标值,上述语句的运行结果如下: Please enter the coordinates of p23: 0 0 Please enter the coordinates of p31: 0 0 5 Please enter the coordinates of p24: 0 0 5 Does (0.0, 0.0) coincide with (0.0, 0.0, 5.0)? -- true Does (0.0, 0.0, 5.0) coincide with (0.0, 0.0)? -- true Does (0.0, 0.0, 5.0) coincide with (0.0, 0.0, 5.0)? -- true Does (0.0, 0.0, 5.0) coincide with (0.0, 0.0, 5.0)? -- true Does (0.0, 0.0) coincide with (0.0, 0.0, 5.0)? -- true Does (0.0, 0.0, 5.0) coincide with (0.0, 0.0)? -- true 该结果显然不符合事实,请分析原因并改进Point2D的代码,使得上述TestPointV2的代码能够得到正确的运行结果。
05-05
上述运行结果不正确的原因在于 Point2D p24 = new Point3D(p24x, p24y, p24z); 这一语句,将一个 Point3D 对象赋值给了 Point2D 型的引用变量 p24,导致在调用 p24.equals(p33) 时出现了错误的结果。 为了解决这个问题,我们需要在 Point2D 中添加一个 equals 方法,用于比较两个点是否相同。具体代码如下: ```java public boolean equals(Object obj) { if (obj instanceof Point2D) { Point2D other = (Point2D) obj; return this.x == other.x && this.y == other.y; } return false; } ``` 这个 equals 方法首先判断参数是否为 Point2D 型,如果是,再将其转换为 Point2D 型进行比较。这样就可以避免上述问题的出现。 修改后的 Point2D 的完整代码如下: ```java public class Point2D { protected double x; protected double y; public Point2D() { this(0, 0); } public Point2D(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } public boolean equals(Object obj) { if (obj instanceof Point2D) { Point2D other = (Point2D) obj; return this.x == other.x && this.y == other.y; } return false; } } ``` 修改后的 TestPointV2 的完整代码如下: ```java import java.util.Scanner; public class TestPointV2 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("Please enter the coordinates of p23:"); double p23x = sc.nextDouble(); double p23y = sc.nextDouble(); Point2D p23 = new Point2D(p23x, p23y); System.out.println("Please enter the coordinates of p31:"); double p31x = sc.nextDouble(); double p31y = sc.nextDouble(); double p31z = sc.nextDouble(); Point3D p33 = new Point3D(p31x, p31y, p31z); System.out.println("Please enter the coordinates of p24:"); double p24x = sc.nextDouble(); double p24y = sc.nextDouble(); double p24z = sc.nextDouble(); sc.close(); // The reference of the parent class refers to the object of the subclass. Point2D p24 = new Point3D(p24x, p24y, p24z); System.out.println("Does " + p23 + " coincide with " + p33 + "? -- " + p23.equals(p33)); System.out.println("Does " + p33 + " coincide with " + p23 + "? -- " + p33.equals(p23)); System.out.println("Does " + p33 + " coincide with " + p24 + "? -- " + p33.equals(p24)); System.out.println("Does " + p24 + " coincide with " + p33 + "? -- " + p24.equals(p33)); System.out.println("Does " + p23 + " coincide with " + p24 + "? -- " + p23.equals(p24)); System.out.println("Does " + p24 + " coincide with " + p23 + "? -- " + p24.equals(p23)); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值