精华内容
下载资源
问答
  • `matplotlib`有两种绘图方式,...这两种方式之间并不是完全独立的,而是通过某种机制进行了联结,`pylot`绘图模式其实隐式创建了面向对象模式的相关对象,其中的关键是`matplotlib._pylab_helpers`模块中的单例类`Gcf`

    matplotlib有两种绘图方式,一种是依托matplotlib.pyplot模块实现类似matlab绘图指令的绘图方式,一种是面向对象式绘图,依靠FigureCanvas(画布)、 Figure (图像)、 Axes (轴域) 等对象绘图。
    这两种方式之间并不是完全独立的,而是通过某种机制进行了联结,pylot绘图模式其实隐式创建了面向对象模式的相关对象,其中的关键是matplotlib._pylab_helpers模块中的单例类Gcf,它的作用是追踪当前活动的画布及图像。
    因此,可以说matplotlib绘图的基础是面向对象式绘图,pylot绘图模式只是一种简便绘图方式。

    先不分析源码,先做实验!

    实验

    先通过实验,看一看我们常用的那些pyplot绘图模式
    实验一
    无绘图窗口显示

    from matplotlib import pyplot as plt
    plt.show()
    

    实验二
    出现绘图结果

    from matplotlib import pyplot as plt
    plt.plot([1,2])
    plt.show()
    

    实验三
    出现绘图结果

    from matplotlib import pyplot as plt
    plt.gca()
    plt.show()
    

    实验四
    出现绘图结果

    from matplotlib import pyplot as plt
    plt.figure()
    # 或者plt.gcf()
    plt.show()
    

    pyplot模块绘图原理

    通过查看pyplot模块figure()函数、gcf()函数、gca()函数、plot()函数和其他绘图函数的源码,可以简单理个思路!

    • figure()函数:如果有现成图像,返回值就是当前图像,如果没有现成的图像,就初始化一个新图像,返回值为Figure对象。
    • gcf()函数:如果有现成图像,返回值就是当前图像,如果没有现成的图像,就调用figure()函数,返回值为Figure对象。
    • gca()函数:调用gcf()函数返回对象的gca方法,返回值为Axes对象。
    • plot()函数:调用gca()函数返回对象的plot方法。
    • pyplot模块其他绘图函数:均调用gca()函数的相关方法。

    因此,pyplot绘图模式,使用plot()函数或者其他绘图函数,如果没有现成图像对象,直接会先创建图像对象。
    当然使用figure()函数、gcf()函数和gca()函数,如果没有现成图像对象,也会先创建图像对象。

    更进一步,在matplotlib.pyplot模块源码中出现了如下代码,因此再查看matplotlib._pylab_helpers模块它的作用是追踪当前活动的画布及图像

    figManager = _pylab_helpers.Gcf.get_fig_manager(num)
    figManager = _pylab_helpers.Gcf.get_active()
    

    matplotlib._pylab_helpers模块作用是管理pyplot绘图模式中的图像。该模块只有一个类——Gcf,它的作用是追踪当前活动的画布及图像。

    matplotlib.pyplot模块部分源码

    def figure(num=None,  # autoincrement if None, else integer from 1-N
               figsize=None,  # defaults to rc figure.figsize
               dpi=None,  # defaults to rc figure.dpi
               facecolor=None,  # defaults to rc figure.facecolor
               edgecolor=None,  # defaults to rc figure.edgecolor
               frameon=True,
               FigureClass=Figure,
               clear=False,
               **kwargs
               ):
    
        figManager = _pylab_helpers.Gcf.get_fig_manager(num)
        if figManager is None:
            max_open_warning = rcParams['figure.max_open_warning']
    
            if len(allnums) == max_open_warning >= 1:
                cbook._warn_external(
                    "More than %d figures have been opened. Figures "
                    "created through the pyplot interface "
                    "(`matplotlib.pyplot.figure`) are retained until "
                    "explicitly closed and may consume too much memory. "
                    "(To control this warning, see the rcParam "
                    "`figure.max_open_warning`)." %
                    max_open_warning, RuntimeWarning)
    
            if get_backend().lower() == 'ps':
                dpi = 72
    
            figManager = new_figure_manager(num, figsize=figsize,
                                            dpi=dpi,
                                            facecolor=facecolor,
                                            edgecolor=edgecolor,
                                            frameon=frameon,
                                            FigureClass=FigureClass,
                                            **kwargs)
        return figManager.canvas.figure
    
    def plot(*args, scalex=True, scaley=True, data=None, **kwargs):
        return gca().plot(
            *args, scalex=scalex, scaley=scaley,
            **({"data": data} if data is not None else {}), **kwargs)
    
    def gcf():
        """
        Get the current figure.
    
        If no current figure exists, a new one is created using
        `~.pyplot.figure()`.
        """
        figManager = _pylab_helpers.Gcf.get_active()
        if figManager is not None:
            return figManager.canvas.figure
        else:
            return figure()
    
    def gca(**kwargs):
        return gcf().gca(**kwargs)
    
    def get_current_fig_manager():
        """
        Return the figure manager of the current figure.
    
        The figure manager is a container for the actual backend-depended window
        that displays the figure on screen.
    
        If if no current figure exists, a new one is created an its figure
        manager is returned.
    
        Returns
        -------
        `.FigureManagerBase` or backend-dependent subclass thereof
        """
        return gcf().canvas.manager
    

    Gcf类源码

    class Gcf:
        """
        Singleton to maintain the relation between figures and their managers, and
        keep track of and "active" figure and manager.
    
        The canvas of a figure created through pyplot is associated with a figure
        manager, which handles the interaction between the figure and the backend.
        pyplot keeps track of figure managers using an identifier, the "figure
        number" or "manager number" (which can actually be any hashable value);
        this number is available as the :attr:`number` attribute of the manager.
    
        This class is never instantiated; it consists of an `OrderedDict` mapping
        figure/manager numbers to managers, and a set of class methods that
        manipulate this `OrderedDict`.
    
        Attributes
        ----------
        figs : OrderedDict
            `OrderedDict` mapping numbers to managers; the active manager is at the
            end.
        """
    
    展开全文
  • 类(对象之间的四种关系

    千次阅读 2016-04-07 19:44:37
    类(对象之间的4种关系  a、依赖关系(Dependency)  所谓依赖就是某个对象的功能依赖于另外的某个对象,而被依赖的对象只是作为一种工具在使用,而并不持有对它的引用  举例:一个人自创生就需要不停的呼吸...

    类(对象)之间的4种关系
       a、依赖关系(Dependency)
        所谓依赖就是某个对象的功能依赖于另外的某个对象,而被依赖的对象只是作为一种工具在使用,而并不持有对它的引用

        举例:一个人自创生就需要不停的呼吸,而人的呼吸功能之所以能维持生命就在于吸进来的气体发挥了作用,所以说空气只不过是人类的一个工具,而人并不持有对它的引用。
       b、关联关系(Association)
        某个对象会长期的持有另一个对象的引用,而二者的关联往往也是相互的。
        关联的两个对象彼此间没有任何强制性的约束,只要二者同意,可以随时解除关系或是进行关联,
        它们在生命期问题上没有任何约定。被关联的对象还可以再被别的对象关联,所以关联是可以共享的。

        举例:人从生至死都在不断的交朋友,然而没有理由认为朋友的生死与我的生死有必然的联系,故他们的生命期没有关联,我的朋友又可以是别人的朋友,所以朋友可以共享。
       c、聚合关系(Aggregation)
        聚合是强版本的关联。
        它暗含着一种所属关系以及生命期关系。
        被聚合的对象还可以再被别的对象关联,所以被聚合对象是可以共享的。
        虽然是共享的,聚合代表的是一种更亲密的关系。

        举例:我的家和我之间具有着一种强烈的所属关系,
        我的家是可以分享的,而这里的分享又可以有两种。
        其一是聚合间的分享,这正如你和你媳妇儿都对这个家有着同样的强烈关联;
        其二是聚合与关联的分享,如果你的朋友来家里吃个便饭,估计你不会给他配一把钥匙。
       d、组合关系(Compostion)
        组合是关系当中的最强版本,它直接要求包含对象对被包含对象的拥有以及包含对象与被包含对象生命期的关系。
        被包含的对象还可以再被别的对象关联,
        所以被包含对象是可以共享的,
        然而绝不存在两个包含对象对同一个被包含对象的共享。

        举例:组合关系就是整体与部分的关系,部分属于整体,
        整体不存在,部分一定不存在,然而部分不存在整体是可以存在的,
        说的更明确一些就是部分必须创生于整体创生之后,而销毁于整体销毁之前。
                                   /**
    一 ·  依赖关系

     *
     * 所谓依赖关系,就是指其中一个对象依赖于另一个对象的某种功能或者属性,就是说,依赖者把被依赖着当作工具来使用,
     * 被依赖者并不属于依赖者。
     *
     * 一个人从出生开始就需要不停的呼吸,那么呼吸需要依赖于空气中的氧气,所以说Human依赖于Air释放的空气,
     * 但是Air又不是属于Human
     *
     */
    public class Dependency {
     public static void main(String []args){
      Human person = new Human();
      while(true){
       person.breath();
      }
     }
    }

    /**
     * 属于依赖者
     * @author Administrator
     *
     */
    class Human{
     public void breath(){
      Air freshAir = new Air();
      freshAir.provideOxygen();
      System.out.println("吸了一口");
      System.out.println("呼了一口");
     }
    }

    /**
     * 属于被依赖者
     * @author Administrator
     *
     */
    class Air{
     public void provideOxygen(){
      System.out.println("释放了一波氧气");
     }
    }    
                          
      import java.util.ArrayList;


    二·关联关系


    /**
     *     所谓关联,某个对象长期持有另一个对象的引用,
        而且这两者之前的关联是相互的,
        关联的两个对象彼此之间没有任何的强制性约束,
        只要两者同意,可以随时解除关联关系,
        而且它们在生命周期上没有任何约定,
        被关联的对象是共享,它还可以被其他对象关联。
     * @author Administrator
     *
     */
    public class Association {
     public static void main(String[] args) {
      Human$ person = new Human$();
      School zhengZhouHighSchool = new School();
      while(true){
       person.makeFriend(zhengZhouHighSchool.getStudent());
      }
     }
    }

    class Human${
     ArrayList friends = new ArrayList();
     public void makeFriend(Human$ hunman$){
      friends.add(hunman$);
     }
    }

    class School{
     public Human$ getStudent(){
      return new Human$();
     }
    }
                           
     

    三   聚合关系

        * @author Administrator
        *家庭和我之间属于一种比较亲密的关系,而且我的家庭是可以分享,我回家以及我家人回家,这种分享具有跟强的亲密度
        *朋友去我家,亲密度要小于我和我家人。
        */
        public class Aggregation {
       public static void main(String[] args) {
        Human$$ person = new Human$$();
      while(true){
       //吃饭
       //上学
       //放学
       person.goHome();
      }
     }
    }

    class Human$${
     Home myHome = new Home();
     public void goHome(){
      myHome.openDoor();
     }
    }

    class Home{
     public void openDoor(){
      
     }
    }

    import java.util.ArrayList;

     


    四  组合关系

     * @author Administrator
     * 组合关系就是整体与部分的关系,部分属于整体,整体不存在,则部分一定不存在
     * 然后部分不存在整体依然可以生存
     * 部分存在于整体创建之后,部分销毁于整体销毁之前。
     */
    public class Compostion {
     public static void main(String[] args) {
      Human$$$ person = new Human$$$();
      while(true){
       person.heart.beat();
      }
     }

    }

    class Human$$${
     Heart heart = new Heart();
    }

    class Heart{
     public void beat(){
      
     }
    }

    展开全文
  • 面向对象模型之间关系

    万次阅读 2017-03-11 16:39:14
    功能模型指明了系统应该“做什么”;动态模型明确规定了什么时候(即在何种状态下接受了什么事件的...在面向对象方法学中,对象模型是最基本最重要的,它为其他两种模型奠定了基础,人们依靠对象模型完成3种模型的集成。

    功能模型指明了系统应该“做什么”动态模型明确规定了什么时候(即在何种状态下接受了什么事件的触发)做对象模型定义了做事情的实体。在面向对象方法学中,对象模型是最基本最重要的,它为其他两种模型奠定了基础,人们依靠对象模型完成3种模型的集成。

    展开全文
  • 在学习面向对象设计对象关系时,依赖、关联、聚合和组合这四种关系之间区别比较容易混淆。特别是后三种,仅仅是在语义上有所区别,所谓语义就是指上下文环境、特定情景等。他们在编程语言中的体现却是基本相同的,...

    在学习面向对象设计对象关系时,依赖、关联、聚合和组合这四种关系之间区别比较容易混淆。特别是后三种,仅仅是在语义上有所区别,所谓语义就是指上下文环境、特定情景等。他们在编程语言中的体现却是基本相同的,但是基本相同并不等于完全相同,这一点在我的前一篇博文《设计模式中类的关系》中已经有所提及,下面就来详细的论述一下在Java中如何准确的体现依赖、关联、聚合和组合。

    首先看一看书上对这四种关系的定义:

    • 依赖(Dependency)关系是类与类之间的联接。依赖关系表示一个类依赖于另一个类的定义。例如,一个人(Person)可以买车(car)和房子(House),Person类依赖于Car类和House类的定义,因为Person类引用了Car和House。与关联不同的是,Person类里并没有Car和House类型的属性,Car和House的实例是以参量的方式传入到buy()方法中去的。一般而言,依赖关系在Java语言中体现为局域变量、方法的形参,或者对静态方法的调用。
    • 关联(Association)关系是类与类之间的联接,它使一个类知道另一个类的属性和方法。关联可以是双向的,也可以是单向的。在Java语言中,关联关系一般使用成员变量来实现。
    •  聚合(Aggregation) 关系是关联关系的一种,是强的关联关系。聚合是整体和个体之间的关系。例如,汽车类与引擎类、轮胎类,以及其它的零件类之间的关系便整体和个体的关系。与关联关系一样,聚合关系也是通过实例变量实现的。但是关联关系所涉及的两个类是处在同一层次上的,而在聚合关系中,两个类是处在不平等层次上的,一个代表整体,另一个代表部分。
    •  组合(Composition) 关系是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分对象的生命周期,组合关系是不能共享的。代表整体的对象需要负责保持部分对象和存活,在一些情况下将负责代表部分的对象湮灭掉。代表整体的对象可以将代表部分的对象传递给另一个对象,由后者负责此对象的生命周期。换言之,代表部分的对象在每一个时刻只能与一个对象发生组合关系,由后者排他地负责生命周期。部分和整体的生命周期一样。

    ——摘自《Java面向对象编程》,作者:孙卫琴

           以上关系的耦合度依次增强(关于耦合度的概念将在以后具体讨论,这里可以暂时理解为当一个类发生变更时,对其他类造成的影响程度,影响越小则耦合度越弱,影响越大耦合度越强)。由定义我们已经知道,依赖关系实际上是一种比较弱的关联,聚合是一种比较强的关联,而组合则是一种更强的关联,所以笼统的来区分的话,实际上这四种关系、都是关联关系。

            依赖关系比较好区分,它是耦合度最弱的一种,在java中表现为局域变量、方法的形参,或者对静态方法的调用,如下面的例子:Driver类依赖于Car类,Driver的三个方法分别演示了依赖关系的三种不同形式。

    [java]  view plain  copy
    1. class Car {  
    2.     public static void run(){  
    3.         System.out.println("汽车在奔跑");  
    4.     }  
    5. }  
    6.   
    7. class Driver {  
    8.     //使用形参方式发生依赖关系  
    9.     public void drive1(Car car){  
    10.         car.run();  
    11.     }  
    12.     //使用局部变量发生依赖关系  
    13.     public void drive2(){  
    14.         Car car = new Car();  
    15.         car.run();  
    16.     }  
    17.     //使用静态变量发生依赖关系  
    18.     public void drive3(){  
    19.         Car.run();  
    20.     }  
    21. }  

            关联关系在java中一般使用成员变量来实现,有时也用方法形参的形式实现。依然使用Driver和Car的例子,使用方法参数形式可以表示依赖关系,也可以表示关联关系,毕竟我们无法在程序中太准确的表达语义。在本例中,使用成员变量表达这个意思:车是我自己的车,我“拥有”这个车。使用方法参数表达:车不是我的,我只是个司机,别人给我什么车我就开什么车,我使用这个车。

    [java]  view plain  copy
    1. class Driver {  
    2.     //使用成员变量形式实现关联  
    3.     Car mycar;  
    4.     public void drive(){  
    5.         mycar.run();  
    6.     }  
    7.     ...  
    8.     //使用方法参数形式实现关联  
    9.     public void drive(Car car){  
    10.         car.run();  
    11.     }  
    12. }  

            聚合关系是是一种比较强的关联关系,java中一般使用成员变量形式实现。对象之间存在着整体与部分的关系。例如上例中

    [java]  view plain  copy
    1. class Driver {  
    2.     //使用成员变量形式实现聚合关系  
    3.     Car mycar;  
    4.     public void drive(){  
    5.         mycar.run();  
    6.     }  
    7. }  


            假如给上面代码赋予如下语义:车是一辆私家车,是司机财产的一部分。则相同的代码即表示聚合关系了。聚合关系一般使用setter方法给成员变量赋值。

    假如赋予如下语义:车是司机的必须有的财产,要想成为一个司机必须要先有辆车,车要是没了,司机也不想活了。而且司机要是不干司机了,这个车就砸了,别人谁也别想用。那就表示组合关系了。一般来说,为了表示组合关系,常常会使用构造方法来达到初始化的目的,例如上例中,加上一个以Car为参数的构造方法

    [java]  view plain  copy
    1. public Driver(Car car){  
    2.     mycar = car;  
    3. }  


            所以,关联、聚合、组合只能配合语义,结合上下文才能够判断出来,而只给出一段代码让我们判断是关联,聚合,还是组合关系,则是无法判断的。

    展开全文
  • 面向对象--类与类之间的几种关系

    千次阅读 2015-01-16 13:33:42
    一、继承关系 继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。在Java中继承关系通过关键字extends明确标识,在设计时一般没有争议性。在UML...
  • 面向对象中类之间关系详细解析

    千次阅读 2018-04-12 21:31:52
    在软件系统中,类不是孤立存在的,类与类之间的存在相互的关系。记得上软件工程时,老师讲到个范型:传统方法学(结构化方法学)和面向对象方法学(将数据和行为封装在一起)。1.关联关系 1)双向关联 2)单向...
  • 众所周知,平时开发过程中将对象序列化成json字符串常用的工具类一般就三:fastJson、Gson、Jackjson,但是三工具类在将对象进行序列化时与对象的get、set、对象属性之间关系你知道吗,如果知道了,那么下面的...
  • 项目之间总有依赖,比如A Job执行完执行B Job,如下图所示,如何建立依赖呢? 配置上游我们通常喜欢配置上游依赖,在B中配置 配置如下信息。选择在其他项目构建完成后进行构建: Project to watch:依赖的项目...
  • 类和对象之间关系?封装继承多态?

    千次阅读 2018-03-04 09:19:00
    在面向对象的编程思想中把对象的属性和行为分别称为对象的属性和方法,是构成对象个主要因素;在编程中,对象的属性被存储在一些变量里;对象的行为则通过定义方法来实现。三大基本特征:封装,继承,多态。 ...
  • 类和类/对象和对象之间的三大关系

    千次阅读 2018-10-13 18:12:37
    线段上有个点 - has-a - 关联关系 整体不可分割的,叫做强关联/聚合 eg:人有手,车有引擎 人使用了房子 - use-a - 使用,依赖关系 学生是人 - is-a - 继承关系 继承 - 从已经有的类创建新类的过程 提供继承...
  • 之前经历了软件开发工具的、软件工程和UML的学习,发现每个学习环节中,有关面向对象技术的讲解都提到了“很重要”这样的字眼,那么,既然面向对象技术(OOT)如此重要,就避免不了要涉及到面向对象的四种关系。...
  • 类和对象之间关系

    万次阅读 2005-03-08 15:01:00
    从日常生活中看对象 其实对象这个名次对我们来说一点也不陌生,因为我们的日常生活中。...通常我们会以这个对象分类的名称来称呼它,例如路上有许多车子,天空有许多鸟,这里的车子,鸟都只是一种对象的分类
  • 用例图之间的几种关系

    万次阅读 2019-05-03 23:58:54
    用例图之间的几种关系 1.执行者与执行者之间的唯一关系(继承) A.解释 执行者与执行者之间只有一种关系即继承(也叫泛化)。其意义与面向对象过程中的继承关系类似,但它主要强调子类执行者对父类执行者与用例之间的...
  • 对象-关系数据库之间的映射

    千次阅读 2012-11-03 14:49:25
    为什么对象-关系数据库的映射对于现代开发者是一件大事呢?一方面,对象技术(例如 Java 技术)是应用于新软件系统开发的最常见的...因为在对象范例和关系范例之间“阻抗不匹配”。对象范例基于软件工程的一些原理,例
  • 在之前的多篇文章中,我们学会了针对单个...想要显示文章的标签,最原始的作法是:根据文章的id查询查询数据库得到文章对象后,根据其中存储的标签id列表,再进行一次数据库查询得到这篇文章拥有的所有标签对象。这种
  • 在面向对象程序设计时,类与类之间的关系主要分为继承,实现,依赖,关联,聚合,组合六种关系。其中前两种理解很简单,重点是比较容易混淆的后四种。继承(或叫泛化):指的是一个类(称为子类、子接口)继承另外的...
  • UML对象和类之间的相互关系总结

    千次阅读 2009-03-16 11:35:00
    UML中描述对象和类之间相互关系的方式包括:依赖(Dependency)关联(Association)聚合(Aggregation)组合(Composition)泛化(Generalization)实现(Realization)等。 依赖 (Dependency):元素A的变化会...
  • UML描述对象和类之间的相互关系

    千次阅读 2008-12-01 16:09:00
    UML中描述对象和类之间相互关系的方式包括:依赖(Dependency)关联(Association)聚合(Aggregation)组合(Composition)泛化(Generalization)实现(Realization)等。 依赖 (Dependency):元素A的变化会...
  • 类与类之间的几种关系

    万次阅读 2017-03-14 08:30:22
    类与类之间的几种关系 一、继承关系 继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。在Java中继承关系通过关键字extends明确标识...
  • java 类之间的四种关系详解

    千次阅读 2018-09-19 13:59:34
    类间关系有很多种,在大的类别上可以分为两种:纵向关系、横向关系。 纵向关系就是继承关系,它的概念非常明确,也成为OO的三个重要特征之一,这里不过多的讨论。 横向关系较为微妙,按照UML的建议大体上可以分为...
  • UML里类之间的几种关系

    千次阅读 2016-10-12 19:03:01
    UML类图:类图时锻炼OOA(OO analysis)和OOD(OO design)思想的重要工具,有助于OOA、OOD思想的提升。 重点:理解类图中类与类之间的关系的关系以及这种关系在代码中...类与类之间存在泛化,关联,依赖,和聚合四种关系
  • UML类图画法及其之间的几种关系

    千次阅读 2017-04-08 22:29:36
    最近做重构项目,需要画一下类图,发现类图的画法及其之间的几种关系已经淡忘了很多,所以整理总结一下,有问题的地方大家可以一起讨论下。 文章目录如下: 类图画法 类之间的几种关系:泛化(Ge
  • Java学习之深拷贝浅拷贝及对象拷贝的两种思路

    千次阅读 多人点赞 2017-12-18 22:22:01
    Java语言中的深拷贝、浅拷贝以及对象拷贝
  • UML类图中类之间的6种关系与区别

    千次阅读 2018-05-15 10:35:11
    原文:https://blog.csdn.net/it_zjyang/article/details/51355062类与类之间的关系类与类之间的关系可以根据关系的强度依次分为以下五种:依赖关系...--泛化(Generalization)依赖关系依赖关系是五种关系中...
  • 数据、数据对象、数据元素、数据项 我们在学习数据结构时首先熟悉的一定是这四个名词,那么在数据家族里这四位成员都是什么关系呢? 严蔚敏的数据结构c语言版一书中解释是这样的: ...四种关系: 数据:是描述
  • 用例图、类图之间的几种关系

    千次阅读 2018-09-02 20:54:14
    UML用例图  用例图主要是用图来表示系统的主事件流程。它主要用来描述客户的需求,即用户...设计人员根据客户的需求来创建和解释用例图,用来描述软件应具备哪些功能模块以及这些模块之间的调用关系。 用例图...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 803,358
精华内容 321,343
关键字:

对象之间的两种关系