封装、继承、多态

谈到面向对象,你可能会想到面向对象的三个特点:封装、继承和多态。

引用

  1. 软件设计之美

封装

  1. 把紧密相关的信息放在一起,形成一个基础单元。
  2. 将一个一个基础单元组合,一层一层逐步向上构建出更大的单元。

我们设计一个类,先要考虑其对象应该提供哪些行为。然后,我们根据这些行为提供对应的方法,最后才是考虑实现这些方法要有哪些字段。

现实中,我们往往是面向过程去编程,例如最早的DBFirst的设计思想,我们首先设计数据库的表,表有哪些字段,使用ORM生成实体,给每一个实体对象的字段进行赋值。其次我们在BLL层或者Service层做业务逻辑操作。这基本就偏离了面向对象封装的设计理念。

封装的重点在于对象提供了哪些行为而不是有哪些数据。也就是说,即便我们把对象理解成数据加函数,数据和函数也不是对等的地位。函数是接口,而数据是内部的实现,正如我们一直说的那样,接口是稳定的,实现是易变的。

C# 9.0 提供了一个新的类型:records

record RecordPerson
{
    public string Name { get; init; }

    public int Age { get; init; }
}
复制代码

简单理解,对于Record对象,他的属性只允许初始化,不允许修改。当一个对象对外暴露过多的细节,就会导致这个对象不稳定。随着需求的变化,如果一个业务处理四处都在修改对象的Age属性,那么出现bug的概率会越来越高,并且难以排查。

对于一个对象来说,封装在于我们提供了哪些行为,而不是getter 和 setter这种暴露内部细节的字段或者属性。

很多团队非常随意地在系统里面添加接口,一个看似不那么复杂的系统里,随随便便就有成百上千个接口。

如果你想改造系统去掉一些接口时,很有可能会造成线上故障,因为你根本不知道哪个团队在什么时候用到了它。所以,在软件设计中,暴露接口需要非常谨慎。
最小化接口暴露。也就是,每增加一个接口,你都要找到一个合适的理由。

继承

在我大学和工作中,部门铜须理解面向对象的第一个概念,就是我这个对象继承另一个对象,这就是面向对象了。比如老师和学生,我们抽象出一个Person类,他们都有Name,Age,在Person中实现一个Introduction的接口,那么我的老师和学生就能复用这个方法了。

Demo

    public class Person
    {
        public string Name { get; set; }

        public int Age { get; set; }

        public void Introduction()
        {
            Console.WriteLine($"I am {Name}, Age:{Age}!");
        }
    }

    public class Student : Person {}
    
    public class Teacher : Person{}
复制代码

这种使用方式,在C#、Java的语法规范中并没有什么问题,但这个真的是继承使用的正确姿势吗?

组合优于继承

如果一个方案既能用组合实现,也能用继承实现,那就选择用组合实现。

在C#、Java都是属于单继承的语言设计,每个类只能有一个父类,一旦继承被实现继承占据了,在想做接口继承就会很麻烦。也就是说,把实现继承当作一种代码复用的方式,并不是一种值得鼓励的做法

总结来说:组合优于继承,继承是为了实现多态,而不是复用。

多态

一个接口,多种形态

Java多态实现


interface Shape {
  // 绘图接口
  void draw();
}

class Square implements Shape {
  void draw() {
    // 画一个正方形
  }
}

class Circle implements Shape {
  void draw() {
    // 画一个圆形
  }
}
复制代码

Go多态实现

type Shape interface {
	draw()
}

type Square struct
{

}

func (s Square) draw() {
	// 画一个正方形
}

type Circle struct
{

}

func (c Circle) draw() {
	// 画一个圆形
}
复制代码

理解多态,还要理解好接口。它是将变的部分和不变的部分隔离开来,在二者之间建立起一个边界。一个重要的编程原则就是面向接口编程,这是很多设计原则的基础。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享