欢迎访问www.allbetgaming.com!

首页科技正文

allbet gmaing代理:面向对象编程中的封装、抽象、继续、多态特征以及应用

admin2020-09-2547

明白面向工具编程及面向工具编程语言的要害就是明白其四大特征:封装、抽象、继续、多态。不外,对于这四大特征,光知道它们的界说是不够的,我们还要知道每个特征存在的意义和目的,以及它们能解决哪些编程问题

封装(Encapsulation)

首先,我们来看封装特征。封装也叫作信息隐藏或者数据接见珍爱。类通过露出有限的接见接口,授权外部仅能通过类提供的方式(或者叫函数)来接见内部信息或者数据。这句话怎么明白呢?我们通过一个简朴的例子来注释一下。下面这段代码是金融系统中一个简化版的虚拟钱包的代码实现。在金融系统中,我们会给每个用户建立一个虚拟钱包,用来纪录用户在我们的系统中的虚拟钱币量。

public class Wallet {
  private String id;
  private long createTime;
  private BigDecimal balance;
  private long balanceLastModifiedTime;
  // ...省略其他属性...

  public Wallet() {
     this.id = IdGenerator.getInstance().generate();
     this.createTime = System.currentTimeMillis();
     this.balance = BigDecimal.ZERO;
     this.balanceLastModifiedTime = System.currentTimeMillis();
  }

  public String getId() { return this.id; }
  public long getCreateTime() { return this.createTime; }
  public BigDecimal getBalance() { return this.balance; }
  public long getBalanceLastModifiedTime() { return this.balanceLastModifiedTime;  }

  public void increaseBalance(BigDecimal increasedAmount) {
    if (increasedAmount.compareTo(BigDecimal.ZERO) < 0) {
      throw new InvalidAmountException("...");
    }
    this.balance.add(increasedAmount);
    this.balanceLastModifiedTime = System.currentTimeMillis();
  }

  public void decreaseBalance(BigDecimal decreasedAmount) {
    if (decreasedAmount.compareTo(BigDecimal.ZERO) < 0) {
      throw new InvalidAmountException("...");
    }
    if (decreasedAmount.compareTo(this.balance) > 0) {
      throw new InsufficientAmountException("...");
    }
    this.balance.subtract(decreasedAmount);
    this.balanceLastModifiedTime = System.currentTimeMillis();
  }
}

从代码中,我们可以发现,Wallet 类主要有四个属性(也可以叫作成员变量),也就是我们前面界说中提到的信息或者数据。其中,id 示意钱包的唯一编号,createTime 示意钱包建立的时间,balance 示意钱包中的余额,balanceLastModifiedTime 示意上次钱包余额调换的时间。

我们参照封装特征,对钱包的这四个属性的接见方式进行了限制。挪用者只允许通过下面这六个方式来接见或者修改钱包里的数据。

  • String getId()

  • long getCreateTime()

  • BigDecimal getBalance()

  • long getBalanceLastModifiedTime()

  • void increaseBalance(BigDecimal increasedAmount)

  • void decreaseBalance(BigDecimal decreasedAmount)

之以是这样设计,是由于从营业的角度来说,id、createTime 在建立钱包的时刻就确定好了,之后不应该再被改动,以是,我们并没有在 Wallet 类中,露出 id、createTime 这两个属性的任何修改方式,好比 set 方式。而且,这两个属性的初始化设置,对于 Wallet 类的挪用者来说,也应该是透明的,以是,我们在 Wallet 类的组织函数内部将其初始化设置好,而不是通过组织函数的参数来外部赋值。

对于钱包余额 balance 这个属性,从营业的角度来说,只能增或者减,不会被重新设置。以是,我们在 Wallet 类中,只露出了 increaseBalance() 和 decreaseBalance() 方式,并没有露出 set 方式。对于 balanceLastModifiedTime 这个属性,它完全是跟 balance 这个属性的修改操作绑定在一起的。只有在 balance 修改的时刻,这个属性才会被修改。以是,我们把 balanceLastModifiedTime 这个属性的修改操作完全封装在了 increaseBalance() 和 decreaseBalance() 两个方式中,不对外露出任何修改这个属性的方式和营业细节。这样也可以保证 balance 和 balanceLastModifiedTime 两个数据的一致性。

封装特征的界说讲完了,我们再来看一下,封装的意义是什么?它能解决什么编程问题?

若是我们对类中属性的接见不做限制,那任何代码都可以接见、修改类中的属性,虽然这样看起来加倍天真,但从另一方面来说,过分天真也意味着不可控,属性可以随意被以种种奇葩的方式修改,而且修改逻辑可能散落在代码中的各个角落,势必影响代码的可读性、可维护性。好比某个同事在不领会营业逻辑的情况下,在某段代码中“偷偷地”重设了 wallet 中的 balanceLastModifiedTime 属性,这就会导致 balance 和 balanceLastModifiedTime 两个数据不一致。

除此之外,类仅仅通过有限的方式露出需要的操作,也能提高类的易用性。若是我们把类属性都露出给类的挪用者,挪用者想要准确地操作这些属性,就势需要对营业细节有足够的领会。而这对于挪用者来说也是一种肩负。相反,若是我们将属性封装起来,露出少许的几个需要的方式给挪用者使用,挪用者就不需要领会太多背后的营业细节,用错的概率就削减许多。这就好比,若是一个冰箱有许多按钮,你就要研究很长时间,还不一定能操作准确。相反,若是只有几个需要的按钮,好比开、停、调治温度,你一眼就能知道该若何来操作,而且操作失足的概率也会降低许多。

抽象(Abstraction)

讲完了封装特征,我们再来看抽象特征。封装主要讲的是若何隐藏信息、珍爱数据,而抽象讲的是若何隐藏方式的详细实现,让挪用者只需要体贴方式提供了哪些功效,并不需要知道这些功效是若何实现的。

在面向工具编程中,我们常借助编程语言提供的接口类(好比 Java 中的 interface 要害字语法)或者抽象类(好比 Java 中的 abstract 要害字语法)这两种语法机制,来实现抽象这一特征。

对于抽象这个特征,我举一个例子来进一步注释一下。

public interface IPictureStorage {
  void savePicture(Picture picture);
  Image getPicture(String pictureId);
  void deletePicture(String pictureId);
  void modifyMetaInfo(String pictureId, PictureMetaInfo metaInfo);
}

public class PictureStorage implements IPictureStorage {
  // ...省略其他属性...
  @Override
  public void savePicture(Picture picture) { ... }
  @Override
  public Image getPicture(String pictureId) { ... }
  @Override
  public void deletePicture(String pictureId) { ... }
  @Override
  public void modifyMetaInfo(String pictureId, PictureMetaInfo metaInfo) { ... }
}

在上面的这段代码中,我们行使 Java 中的 interface 接口语法来实现抽象特征。挪用者在使用图片存储功效的时刻,只需要领会 IPictureStorage 这个接口类露出了哪些方式就可以了,不需要去查看 PictureStorage 类里的详细实现逻辑。

现实上,抽象这个特征是异常容易实现的,并不需要非得依赖接口类或者抽象类这些特殊语法机制来支持。换句话说,并不是说一定要为实现类(PictureStorage)抽象出接口类(IPictureStorage),才叫作抽象。即便不编写 IPictureStorage 接口类,单纯的 PictureStorage 类自己就知足抽象特征。

之以是这么说,那是由于,类的方式是通过编程语言中的“函数”这一语法机制来实现的。通过函数包裹详细的实现逻辑,这自己就是一种抽象。挪用者在使用函数的时刻,并不需要去研究函数内部的实现逻辑,只需要通过函数的命名、注释或者文档,领会其提供了什么功效,就可以直接使用了。好比,我们在使用 C 语言的 malloc() 函数的时刻,并不需要领会它的底层代码是怎么实现的。

抽象有时刻会被清扫在面向工具的四大特征之外,那时我卖了一个关子,现在我就来注释一下为什么。

抽象这个观点是一个异常通用的设计头脑,并不单单用在面向工具编程中,也可以用来指导架构设计等。而且这个特征也并不需要编程语言提供特殊的语法机制来支持,只需要提供“函数”这一异常基础的语法机制,就可以实现抽象特征、以是,它没有很强的“特异性”,有时刻并不被看作面向工具编程的特征之一。

抽象特征的界说讲完了,我们再来看一下,抽象的意义是什么?它能解决什么编程问题?

现实上,若是上升一个思索层面的话,抽象及其前面讲到的封装都是人类处置庞大性的有用手段。在面临庞大系统的时刻,人脑能蒙受的信息庞大水平是有限的,以是我们必须忽略掉一些非要害性的实现细节。而抽象作为一种只关注功效点不关注实现的设计思绪,正好帮我们的大脑过滤掉许多非需要的信息。

除此之外,抽象作为一个异常宽泛的设计头脑,在代码设计中,起到异常重要的指导作用。许多设计原则都体现了抽象这种设计头脑,好比基于接口而非实现编程、开闭原则(对扩睁开放、对修改关闭)、代码解耦(降低代码的耦合性)等。我们在讲到后面的内容的时刻,会详细来注释。

换一个角度来思量,我们在界说(或者叫命名)类的方式的时刻,也要有抽象头脑,不要在方式界说中,露出太多的实现细节,以保证在某个时间点需要改变方式的实现逻辑的时刻,不用去修改其界说。举个简朴例子,好比 getAliyunPictureUrl() 就不是一个具有抽象头脑的命名,由于某一天若是我们不再把图片存储在阿里云上,而是存储在私有云上,那这个命名也要随之被修改。相反,若是我们界说一个对照抽象的函数,好比叫作 getPictureUrl(),那即便内部存储方式修改了,我们也不需要修改命名。

继续(Inheritance)

学习完了封装和抽象两个特征,我们再来看继续特征。若是你熟悉的是类似 Java、C++ 这样的面向工具的编程语言,那你对继续这一特征,应该不陌生了。继续是用来示意类之间的 is-a 关系,好比猫是一种哺乳动物。从继续关系上来讲,继续可以分为两种模式,单继续和多继续。单继续示意一个子类只继续一个父类,多继续示意一个子类可以继续多个父类,好比猫既是哺乳动物,又是爬行动物。

继续特征的界说讲完了,我们再来看,继续存在的意义是什么?它能解决什么编程问题?

继续最大的一个利益就是代码复用。如果两个类有一些相同的属性和方式,我们就可以将这些相同的部门,抽取到父类中,让两个子类继续父类。这样,两个子类就可以重用父类中的代码,制止代码重复写多遍。不外,这一点也并不是继续所独占的,我们也可以通过其他方式来解决这个代码复用的问题,好比行使组合关系而不是继续关系。

若是我们再上升一个头脑层面,去思索继续这一特征,可以这么明白:我们代码中有一个猫类,有一个哺乳动物类。猫属于哺乳动物,从人类认知的角度上来说,是一种 is-a 关系。我们通过继续来关联两个类,反映真实天下中的这种关系,异常相符人类的认知,而且,从设计的角度来说,也有一种结构美感。

继续的观点很好明白,也很容易使用。不外,过分使用继续,继续条理过深过庞大,就会导致代码可读性、可维护性变差。为了领会一个类的功效,我们不仅需要查看这个类的代码,还需要根据继续关系一层一层地往上查看“父类、父类的父类……”的代码。另有,子类和父类高度耦合,修改父类的代码,会直接影响到子类。

以是,继续这个特征也是一个异常有争议的特征。许多人以为继续是一种反模式。我们应该只管少用,甚至不用。关于这个问题,在后面讲到“多用组合少用继续”这种设计头脑的时刻,我会异常详细地再解说,这里暂时就不睁开解说了。

多态(Polymorphism)

学习完了封装、抽象、继续之后,我们再来看面向工具编程的最后一个特征,多态。多态是指,子类可以替换父类,在现实的代码运行过程中,挪用子类的方式实现。对于多态这种特征,纯文字注释欠好明白,我们照样看一个详细的例子。

public class DynamicArray {
  private static final int DEFAULT_CAPACITY = 10;
  protected int size = 0;
  protected int capacity = DEFAULT_CAPACITY;
  protected Integer[] elements = new Integer[DEFAULT_CAPACITY];
  
  public int size() { return this.size; }
  public Integer get(int index) { return elements[index];}
  //...省略n多方式...
  
  public void add(Integer e) {
    ensureCapacity();
    elements[size++] = e;
  }
  
  protected void ensureCapacity() {
    //...若是数组满了就扩容...代码省略...
  }
}

public class SortedDynamicArray extends DynamicArray {
  @Override
  public void add(Integer e) {
    ensureCapacity();
    int i;
    for (i = size-1; i>=0; --i) { //保证数组中的数据有序
      if (elements[i] > e) {
        elements[i+1] = elements[i];
      } else {
        break;
      }
    }
    elements[i+1] = e;
    ++size;
  }
}

public class Example {
  public static void test(DynamicArray dynamicArray) {
    dynamicArray.add(5);
    dynamicArray.add(1);
    dynamicArray.add(3);
    for (int i = 0; i < dynamicArray.size(); ++i) {
      System.out.println(dynamicArray.get(i));
    }
  }
  
  public static void main(String args[]) {
    DynamicArray dynamicArray = new SortedDynamicArray();
    test(dynamicArray); // 打印效果:1、3、5
  }
}

多态这种特征也需要编程语言提供特殊的语法机制来实现。在上面的例子中,我们用到了三个语法机制来实现多态。

  • 第一个语法机制是编程语言要支持父类工具可以引用子类工具,也就是可以将 SortedDynamicArray 传递给 DynamicArray。

  • 第二个语法机制是编程语言要支持继续,也就是 SortedDynamicArray 继续了 DynamicArray,才能将 SortedDyamicArray 传递给 DynamicArray。

  • 第三个语法机制是编程语言要支持子类可以重写(override)父类中的方式,也就是 SortedDyamicArray 重写了 DynamicArray 中的 add() 方式。

通过这三种语法机制配合在一起,我们就实现了在 test() 方式中,子类 SortedDyamicArray 替换父类 DynamicArray,执行子类 SortedDyamicArray 的 add() 方式,也就是实现了多态特征。

接下来,我们先来看若何行使接口类来实现多态特征。我们照样先来看一段代码

public interface Iterator {
  String hasNext();
  String next();
  String remove();
}

public class Array implements Iterator {
  private String[] data;
  
  public String hasNext() { ... }
  public String next() { ... }
  public String remove() { ... }
  //...省略其他方式...
}

public class LinkedList implements Iterator {
  private LinkedListNode head;
  
  public String hasNext() { ... }
  public String next() { ... }
  public String remove() { ... }
  //...省略其他方式... 
}

public class Demo {
  private static void print(Iterator iterator) {
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }
  
  public static void main(String[] args) {
    Iterator arrayIterator = new Array();
    print(arrayIterator);
    
    Iterator linkedListIterator = new LinkedList();
    print(linkedListIterator);
  }
}

多态特征讲完了,我们再来看,多态特征存在的意义是什么?它能解决什么编程问题?

多态特征能提高代码的可扩展性和复用性。为什么这么说呢?我们回过头去看解说多态特征的时刻,举的第二个代码实例(Iterator 的例子)。在那个例子中,我们行使多态的特征,仅用一个 print() 函数就可以实现遍历打印差别类型(Array、LinkedList)聚集的数据。当再增添一种要遍历打印的类型的时刻,好比 HashMap,我们只需让 HashMap 实现 Iterator 接口,重新实现自己的 hasNext()、next() 等方式就可以了,完全不需要改动 print() 函数的代码。以是说,多态提高了代码的可扩展性。

若是我们不使用多态特征,我们就无法将差别的聚集类型(Array、LinkedList)传递给相同的函数(print(Iterator iterator) 函数)。我们需要针对每种要遍历打印的聚集,划分实现差别的 print() 函数,好比针对 Array,我们要实现 print(Array array) 函数,针对 LinkedList,我们要实现 print(LinkedList linkedList) 函数。而行使多态特征,我们只需要实现一个 print() 函数的打印逻辑,就能应对种种聚集数据的打印操作,这显然提高了代码的复用性。

除此之外,多态也是许多设计模式、设计原则、编程技巧的代码实现基础,好比计谋模式、基于接口而非实现编程、依赖倒置原则、里式替换原则、行使多态去掉冗长的 if-else 语句等等。关于这点,在学习后面的章节中,你逐步会有更深的体会。

重点回首

今天的内容就讲完了,我们来一起总结回首一下,你需要重点掌握的几个知识点。

1、关于封装特征

封装也叫作信息隐藏或者数据接见珍爱。类通过露出有限的接见接口,授权外部仅能通过类提供的方式来接见内部信息或者数据。它需要编程语言提供权限接见控制语法来支持,例如 Java 中的 private、protected、public 要害字。封装特征存在的意义,一方面是珍爱数据不被随意修改,提高代码的可维护性;另一方面是仅露出有限的需要接口,提高类的易用性。

2、关于抽象特征

封装主要讲若何隐藏信息、珍爱数据,那抽象就是讲若何隐藏方式的详细实现,让使用者只需要体贴方式提供了哪些功效,不需要知道这些功效是若何实现的。抽象可以通过接口类或者抽象类来实现,但也并不需要特殊的语法机制来支持。抽象存在的意义,一方面是提高代码的可扩展性、维护性,修改实现不需要改变界说,削减代码的改动局限;另一方面,它也是处置庞大系统的有用手段,能有用地过滤掉不需要关注的信息。

3、关于继续特征

继续是用来示意类之间的 is-a 关系,分为两种模式:单继续和多继续。单继续示意一个子类只继续一个父类,多继续示意一个子类可以继续多个父类。继续主要是用来解决代码复用的问题。

4、关于多态特征

多态是指子类可以替换父类,在现实的代码运行过程中,挪用子类的方式实现。多态可以提高代码的扩展性和复用性,是许多设计模式、设计原则、编程技巧的代码实现基础。

,

Allbet Gaming

www.kingtaowang.com欢迎进入欧博平台网站(Allbet Gaming),Allbet Gaming开放欧博平台网址、欧博注册、欧博APP下载、欧博客户端下载、欧博真人游戏(百家乐)等业务。

转载声明:本站发布文章及版权归原作者所有,转载本站文章请注明文章来源!

本文链接:https://www.qicaihuayang.com/post/844.html

网友评论

1条评论
  • 2020-09-25 00:00:54

    欧博电脑版欢迎进入欧博电脑版(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。我也想写,求教

最新评论

  • 环球UG官网 10/23 说:

    apple developer enterprise account for rentproviding apple enterprise developer accounts for rent, rent your own enterprise account for app signing. with high quality, stable performance and affordable price.值得看的

  • 环球UG官网 10/23 说:

    apple developer enterprise account for rentproviding apple enterprise developer accounts for rent, rent your own enterprise account for app signing. with high quality, stable performance and affordable price.值得看的

  • 环球UG开户 10/22 说:

    欧博手机版下载欢迎进入欧博手机版下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。老夫心动了怎么办

  • 环球UG开户 10/22 说:

    欧博手机版下载欢迎进入欧博手机版下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。老夫心动了怎么办

  • UG环球客户端 10/20 说:

    欧博手机版欢迎进入欧博手机版(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。可以提问吗?好奇

  • AllbetGmaing手机版下载 10/20 说:

    Allbetwww.aLLbetgame.us欢迎进入Allbet平台(Allbet Gaming):www.aLLbetgame.us,欧博平台开放欧博(Allbet)开户、欧博(Allbet)代理开户、欧博(Allbet)电脑客户端、欧博(Allbet)APP下载等业务。感觉已经火了

  • UG环球 10/18 说:

    欧博allbet注册欢迎进入欧博allbet注册(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。就是很好,谁损也没用

  • UG环球 10/18 说:

    欧博allbet注册欢迎进入欧博allbet注册(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。就是很好,谁损也没用