(正在更新)[第12-13天] Java、C#、Golang 浅谈面向对象 类与继承的比较


本文介绍

Java、C#、Golang 这三门编程语言关于面向对象都各自有不同的写法。本人在学习的时候为了防止自己弄混各个语言的面向对象知识,便写下此篇文章浅谈这三门编程语言面向对象,进行类与继承的比较。本文重点从案例入手,从各个编程语言的案例,找出相同点与不同点,从而加深印象,也供广大读者参考

面向对象的三大特征

类的对象由什么组成及在这个对象上可执行什么操作。对象是类的实例。构成类的方法和变量称为类的成员。

  • 对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
  • :类是一个模板,它描述一类对象的行为和状态。

面向对象的三大特征

(一)封装:隐藏对象的属性和实现细节,仅对外提供访问方式

(二)继承:使得子类具有父类的属性和方法或重新定义、追加方法和属性等

(三)多态:不同对象中同种行为的不同实现方式

动物园里有很多动物,比如 鸟、兔子 。 鸟和兔子 都是动物,动物是一个基类(又叫父类、超类),这个基类有一些抽象的方法和属性,Eat() Sleep() Run()...,Age, Name....。鸟和兔子是派生类,继承了父类的属性和方法,各自又有不同点,鸟有翅膀,兔子有长耳朵,就可以各自增加属性和方法,这是继承,鸟和兔子能吃的东西也不一样,所以他们Eat()的方法不一样,各自重写了父类的Eat(),这叫重写,兔子可以吃胡萝卜 Eat(胡萝卜),也可以胡萝卜跟白菜一起吃 Eat(胡萝卜,白菜),同一个方法有不同的参数列表,这叫重载。我只知道鸟、兔子实对象的 Eat() Sleep() Run() 能做什么,直接调用就好,不用知道它是怎么实现的就是封装。鸟和兔子都会跑,但是鸟是飞着跑,兔子是奔跑,两者 Run() 的实现方式不一样,不同对象同一行为的不同实现方式,这就是多态

案例一

蚩尤 老师给的作业:创建一个平面形状类,包含相应属性和方法。再创建一个立体图形类,使用该平面对象类为底,并利用平面形状的面积方法求立体形状的体积。

我们就用这个例子来看 Java、C#、Golang 类与继承的区别。因为本人喜欢C#,先以C#开门见山

C# 写法

代码

using System;

namespace C_Sharp与Java对比
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            Shape2D circle = new Circle(10);
            Console.WriteLine("圆的面积:{0:.00}",circle.getArea());
            Console.WriteLine("圆的周长:{0:.00}",circle.getPerimeter());
            Shape3D cone = new Cone("一号圆锥体",circle,5);
            Console.WriteLine("{1} 的体积:{0:.00}",cone.getVolume(),cone.Name);
        }
    }
    
    public abstract class Shape2D
    {
        protected const double PI = 3.1415926;

        protected Shape2D(){}

        protected Shape2D(string name)
        {
            this.Name = name;
        }        

        public abstract double getArea();
        public abstract double getPerimeter();

        protected string Name { get; set; } = "None";
    }

    public class Circle : Shape2D
    {
        public Circle(string name,double radius) : base(name)
        {
            this.Radius = radius;
        }

        public double Radius { get; set; }

        public Circle(double radius)
        {
            this.Radius = radius;
            Name = "正圆";
        }
        public override double getArea()
        {
            return Radius * Radius * PI;
        }

        public override double getPerimeter()
        {
            return 2 * Radius * PI;
        }
    }

    public abstract class Shape3D
    {
        protected Shape3D() { }

        protected Shape3D(string name)
        {
            this.Name = name;
        }


        public string Name { get; set; } = "None";

        public abstract double getVolume();
    }

    public class Cone : Shape3D
    {
        public Shape2D Bottom { get; set; }

        public Cone(Shape2D bottom,double height)
        {
            this.Bottom = bottom;
            this.Height = height;
            Name = "圆锥体";
        }

        public Cone(string name,Shape2D bottom,double height) : base(name)
        {
            this.Bottom = bottom;
            this.Height = height;
        }
        public void setHeight(double height)
        {
            this.Height = height;
        }
        public double Height { get; set; }

        public override double getVolume()
        {
            return Bottom.getArea() * Height / 3;
        }
    }
}

类的写法

 class  class_name
{
    // member variables
      variable1;
      variable2;
    ...
      variableN;
    // member methods
      method1(parameter_list)
    {
        // method body
    }
      method2(parameter_list)
    {
        // method body
    }
    ...
      methodN(parameter_list)
    {
        // method body
    }
}
  • 访问标识符 指定了对类及其成员的访问规则。如果没有指定,则使用默认的访问标识符。类的默认访问标识符是 internal,成员的默认访问标识符是 private
  • 数据类型 指定了变量的类型,返回类型 指定了返回的方法返回的数据类型。
  • 如果要访问类的成员,你要使用点(.)运算符。如 dog.sleep()
  • 点运算符链接了对象的名称和成员的名称。 上条的解释