PHPJAVA

java,php,go之「面向对象入门」

2020-03-19  本文已影响0人  木云先森

面向过程和面向对象

这是两个经常一起提到的概念,所谓面向过程,指的是按照我们的顺序思路,堆砌我们的代码和功能。

面向对象呢,就是把东西都当成了对象,进行对象直接的操作。那什么是对象呢,很多书籍,喜欢用生物学的逻辑去讲,这样好理解一点,大家可以自行去搜索。

我们主要探讨点就是,为什么要面向对象。原因很简单,因为是一种更高的抽象,可以站在更高的维度去看待业务需求。可以把很复杂的问题,拆分成更细小的问题去解决。也可以提高我们的代码重用率,增加系统的稳定性。

封装

封装是对象最基本的特性,对象其实就是数据和方法的集合,这个认知个人觉得还是蛮重要的。在此基础之上,还有个重要的认知就是,数据和方法都有自己的访问权限

举例更直观(php)

class Promotion{

  protected $total;
  protected $discount;
  
  //构造函数,初始化数据
  function __construct($total, $discount)
  {
    $this ->total = $total;
    $this ->discount = $discount;
  }

  //获得需要抵扣的金额
  public function getDiscountPirce()
  {
    return $this->discount;
  }
 }

对上述的内容,做一些简单的说明

  1. 多了一个关键词,class
  2. __construct为构造函数,就是实例化后,就会首先运行的方法
  3. 不管是数据还是方法,会有public, protected, private的访问修饰符

注意点:把类当初一种复杂的特殊的数据类型,可以存放各种权限控制的数据,也可以有各种权限的方法。

举例更直观(java)

class Promoiton{
    protected double total;
    protected int discount;
    //构造函数,初始化数据
    public Promoiton(double $total, int $discount){
        this.total = $total;
        this.discount = $discount;
    }

    //运算对应的促销减去的金额
    public double getDiscountPirce(){
        return this.discount;
    }
}

对上述的内容,做一些简单的说明

  1. 和上面的php代码对比,其实只有语法差异,比如需要定义更完善的类型等

举例更直观(python)

class Promotion:
    #构造函数,初始化数据
    def __init__(self, total, discount):
        self._total = total
        self._discount = discount

    #运算对应的促销减去的金额
    def getDiscountPirce(self):
        return self.discount

对上述的内容,做一些简单的说明

  1. 有个语法特性是,参数中需要传递self关键字。
  2. python使用_xxx __xxx来做外部访问的控制

继承

继承主要是指子类通过语言语法特性,获得父类所有的逻辑的方式。是一种is-a的关系。

举例更直观(php)

//父类
class Promotion{

    protected $total;
    protected $discount;
    //构造函数
    function __construct($total, $discount)
    {
        $this ->total = $total;
        $this ->discount = $discount;
    }

    public function getDiscountPirce()
    {
        return $this->discount;
    }
}

/**
*  满折
*/
class FullDiscount extends promotion
{
    //运行父类构造函数
    function __construct($total, $discount)
    {
        parent::__construct($total, $discount);
    }
}

对上述内容做一些简单的说明

  1. php采用extends关键字,做对应的继承逻辑的支持
  2. 子类会拥有父类的逻辑,这也会带来,修改父类代码,会影响子类的风险

举例更直观(java)

//定义促销类(满减)
class Promoiton{
    protected double total;
    protected int discount;

    public Promoiton(double $total, int $discount){
        this.total = $total;
        this.discount = $discount;
    }

    //运算对应的促销减去的金额
    public double getDiscountPirce(){
        return this.discount;
    }
}

//定义满折(8折传过来的值为80即可)
class FullDiscount extends Promoiton{
    public FullDiscount(double $total, int $discount){
        super($total, $discount);
    }
}

对上述内容做一些简单的说明

  1. 也是采用extends关键字做的继承逻辑支持
  2. 构造函数中,采用了super关键字做父类构造函数调用

举例更直观(python)

class Promotion:
    def __init__(self, total, discount):
        self.total = total
        self.discount = discount

    def getDiscountPirce(self):
        return self.discount

class FullDiscount(Promotion):
    def getDiscountPirce(self):
        return ((100 - self.discount) * self.total) / 100

对上述内容做一些简单的说明

  1. 继承采用的语法关键词是加上 (父类类名) 逻辑
  2. 父类构造不需要再用特殊关键字,会自己进行处理

综上要点说明

  1. 不同的语言会有不同的语法关键字对继承进行支持。但是,其实逻辑上是大同小异的。
  2. 继承最简单的好处就是代码的复用,当然这样也有坏的地方。所以后续我们会讲组合相关的逻辑。以及其他的设计模式对于这块逻辑的一种综述。

多态

可以简单理解为多态,就是语法支持后,继承之后对于父类同名方法的重写。对于一些动态语言,也可以非继承下,做同名方法的各自逻辑实现。

下方的更为复杂的案例,描述的业务场景,就是计算不同促销下,优惠的金额
举例更直观(php)

//父类方法(计算满减金额)
class Promotion{

    protected $total;
    protected $discount;

    function __construct($total, $discount)
    {
        $this ->total = $total;
        $this ->discount = $discount;
    }
    //计算满减的逻辑
    public function getDiscountPirce()
    {
        return $this->discount;
    }
}

/**
*  满折
*/
class FullDiscount extends promotion
{
    function __construct($total, $discount)
    {
        parent::__construct($total, $discount);
    }
    //计算满折的逻辑
    public function getDiscountPirce()
    {
        return ((100 - $this->discount) * $this->total) / 100;
    }   
}

/**
* 积分抵扣
*/
class IntegralDeduction extends promotion
{
    function __construct($total, $discount)
    {
        parent::__construct($total, $discount);
    }
    //计算积分抵扣的逻辑
    public function getDiscountPirce()
    {
        return $this->discount / 10;
    }
}
//实例化促销类,并且计算不同类型的促销优惠
$arr = [
        new Promotion(1000,30),
        new FullDiscount(1000,80),
        new IntegralDeduction(1000,100),
        ];
//计算不同的促销的金额总和
foreach ($arr as $key => $obj) {
    $payment += $obj->getDiscountPirce();
}
echo $payment;

对上述内容做一些简单的说明

  1. 通过子类重写getDiscountPirce方法,做不同类型的促销实现,从而计算出不同的促销价。并得出总值

举例更直观(java)

class Main{
    //入口函数
    public static void main(String[] args) {
        Promoiton[] promoitons = new Promoiton[]{
                new Promoiton(1000,30),
                new FullDiscount(1000, 80),
                new IntegralDeduction(1000, 100),
        };
        System.out.println(getTotal(promoitons));
    }

    //计算总共需要减去的金额
    public static double getTotal(Promoiton... promoitons){
        double payment = 0;
        for (Promoiton promoiton : promoitons){
            payment = payment + promoiton.getDiscountPirce();
        }
        return payment;
    }

}

//定义促销类(满减)
class Promoiton{
    protected double total;
    protected int discount;

    public Promoiton(double $total, int $discount){
        this.total = $total;
        this.discount = $discount;
    }

    //运算对应的促销减去的金额
    public double getDiscountPirce(){
        return this.discount;
    }
}

//定义满折(8折传过来的值为80即可)
class FullDiscount extends Promoiton{
    public FullDiscount(double $total, int $discount){
        super($total, $discount);
    }

    //运算对应的折扣金额
    public double getDiscountPirce(){
        return ((100 - this.discount) * this.total)/100;
    }
}

//定义积分抵扣(积分比例为10:1)
class IntegralDeduction extends Promoiton{
    public IntegralDeduction(double $total, int $discount){
        super($total, $discount);
    }

    //运算对应的折扣金额
    public double getDiscountPirce(){
        return this.discount/10;
    }
}

对上述内容做一些简单的说明

  1. 和上述的php代码相比,就一些语法格式不一样,大同小异

举例更直观(python)

class Promotion:
    def __init__(self, total, discount):
        self._total = total
        self._discount = discount

    def getDiscountPirce(self):
        return self._discount

class FullDiscount(Promotion):
    def getDiscountPirce(self):
        return ((100 - self._discount) * self._total) / 100

class IntegralDeduction(Promotion):
    def getDiscountPirce(self):
        return self._discount / 10;

arr = [Promotion(1000,30), FullDiscount(1000,80), IntegralDeduction(1000,100)];
payment = 0
for obj in arr:
    payment += obj.getDiscountPirce()
print(payment)

对上述内容做一些简单的说明

  1. 和上述的php,java代码相比,除一些语法格式不一样,一样是大同小异。也能侧面看出python代码的简洁

多态的更多实现

除了上述所描述的继承之后的重新方法,实现多态外。一般还有2种办法,可以实现多态。一是通过定义接口方法,二是duck-typing的方式

接口方法实现,后续会有详细的介绍,接口和抽象也是后续需要掌握的一个大的认知点

下面实现duck-typing的方式

class English:
    def record(self):
        print("hello")

class Chinese:
    def record(self):
        print("你好")

def test(recorder):
    recorder.record()

def demo():
    english = English()
    chinese = Chinese()
    test(english)
    test(chinese)
#执行函数
demo()
#输出对应的数据
hello
你好

对上述内容做一些简单的说明

  1. 首先无继承关系。是各自独立的类
  2. 通过使用相同的方法,来进行实例化的时候。也就是类运行过程中,去使用对用的实例类中的方法
    3.一般只有动态语言,支持这种方式
上一篇 下一篇

猜你喜欢

热点阅读