精华内容
下载资源
问答
  • Python之类的三大特性

    2019-12-30 14:02:48
    就是可以将类中的一些属性或者方法隐藏起来,在外界不到,但是用户可以通过给出的接口来调用这部分封装的属性或者方法,这符合我们人类的处事方式,我们电视只需要知道电视的功能而不需要知道电视机的内部是怎么...

    话不多说,直接开讲。

    封装

    封装,就是可以将类中的一些属性或者方法隐藏起来,在外界看不到,但是用户可以通过给出的接口来调用这部分封装的属性或者方法,这符合我们人类的处事方式,我们看电视只需要知道电视的功能而不需要知道电视机的内部是怎么运作的。
    等于说就是类中的部分属性方法不需要展现给用户,只需要提供给外界一个接口,让外界在通过这个接口时,能得到运行封装起来的属性或者方法的数据就OK了。
    那么封装的前提是什么,当然是隐藏了啊 ,只有在类里对数据进行隐藏,外界才不能直接调用,隐藏的方法很简单,就是再想要隐藏的属性或者方法名的前面加上两个下划线就可以了。

    class Teacher:
    	school = "一所大学"
    	__wife = "泷泽某拉"
    	
    	def __init__(self,name):
    		self.name = name
    		
    	def teacher_info(self):
    		return "name:%s wife:%s"%(self.name,self.__wife) 
    	
    

    你直接问老师他的媳妇是谁,老师肯定不愿意,还怀疑你想干什么,但是你通过调取老师的信息这个接口函数,就能看到老师的媳妇是谁了。是不是很神奇?
    那么把属性和方法封装起来,就真的没办法在外界调用了吗??当然不是的 ,既然想在外界调用,那么就要明白封装的原理。
    封装数据是发生在类定义阶段的,也就是说当你在类外面想重新添加一个隐藏的属性是不能做到的,只有在程序丁一阶段才能将数据隐藏起来。
    另一个就是类的隐藏只是改变了函数的调用方式,并不是真正意义的将数据隐藏,通过修改一下调用方式,依然能在外界调用这个属性或者方法。

    class Teacher:
    	school = "一所大学"
    	__wife = "泷泽某拉"
    	
    	def __init__(self,name):
    		self.name = name
    		
    	def teacher_info(self):
    		return "name:%s wife:%s"%(self.name,self.__wife) 
    	
    print(Teacher._Teacher__wife)# 通过_类名__隐藏的属性或者方法就能在外界调用
    

    当然啦,既然我们将它在类里隐藏,那么久是希望不要在外面直接调用,那么直接在外界调用就没有什么意义了。

    封装的意义主要在于展现在外部的简洁化,内部所运行的程序再多,但是出现在外界的就很简单的几个接口,同时,如果是在继承中的话,还能防止父类的属性或者方法被子类的属性或者方法替换,主要还是因为两者的调用方式不同。

    继承

    继承最初要的作用就是减少重复代码。
    站在不同的角度看世间,世间风景是不一样的,同时,我们看到的也是不一样的,首先我们看到了虫、鱼、鸟、兽,这是4个截然不同的类,好的,我们赶紧定义了四个类,然后我们又看到了琴棋书画,抓紧定义了一个琴棋书画4个类,对比我们的八个类,惊奇的发现前4个都属于有生命的,后4个是无生命的,我们又定义了两个类,但是前4个同属于有生命的类中各自又有不同的属性、方法,又有相同的属性和方法,总不能写4遍吧,这个时候,就用到了继承。
    当在类定义的时候指定继承自哪个类,就会默认具备该类的所有属性和方法,B被称为子类,A被称为父类。

    class A:
        school = "一所差大学"
        
        def __init__(self):
            self.grade = 60
            
    class B(A):
        pass
    	
    

    当然,B 肯定不甘心啊 ,一上来就是一个差大学,如果不想要父类的一些属性或者方法,可以定义一个同名属性或者方法,就可以使用自己的了,

    class A:
        school = "一所差大学"
        
        def __init__(self):
            self.grade = 60
            
    class B(A):
        school = “一所好大学”
        
    	def __init__(self):
            self.grade = 100
    

    当然,还可以同时继承多个类,那时,就要涉及到一个查找顺序了,如果子类里面没有这个属性,那么去哪个类找呢?
    你可以使用mro()查看属性的查找顺序,在python3中都成为新式类,默认为广度优先,需要记住,子类会优先父类被查找。
    当在子类中想调用父类中的方法时,我们有两种方法 。
    第一种就是直接调用父类的方法。在子类中利用(父类名.父类方法())。
    第二种就是利用继承的关系来确定(super().方法名())。查找的顺序就是按照mro 列表来查找。

    多态

    多态:一个类可以有多种形态。
    多态性:在不考虑实例类型的情况下直接使用实例。
    多态性可以分为静态多态性和动态多态性。
    在说多态之间,应该先介绍一下抽象类与归一化。

    抽象类与归一化

    抽象类就是不能被实例化只能被继承的类。
    Python中并没有抽象类的概念,但是可以借助abc这个模块来实现类似的功能,所有继承抽象类的类,必须实现抽象类中定义的所有函数属性。这样多有继承抽象类的类都必须拥有这个抽象类的函数属性,在调用的时候,就可以在外界定义一个接口函数,所有继承抽象类的类都可以不考虑自己的实际类型而直接调用这个接口函数了,这样就实现了归一化的作用。

    import abc
    
    class AllFile(metaclass=abc.ABCMeta):
        all_file = "一切皆文件"
        
        @abc.abstractmethod
        def read(self):
            pass
        
        @abc.abstractmethod
        def write(self):
            pass
    

    下面我们就了解一下什么是多态。多态就是一个类具有多种形态,“龙生九子,九子不同”大概就是这个道理了,多态性主要是在继承的背景下使用的,分为动态多态性和静态多态性。动态多态性就类似于抽象类和归一化的综合应用,静态多态性就是类似于Python函数中的+的使用。

    展开全文
  • 封装,既然作为三大特性之一,什么是封装,怎么封装,以及封装有什么好处? 先一下比较官方的一种定义:封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。面向对象计算始于这个基本概念,即现实...

    我们知道,我们通常所说的面向对象编程有三大特性,继承,封装与多态。

    封装,既然作为三大特性之一,什么是封装,怎么封装,以及封装有什么好处?

    先看一下比较官方的一种定义:封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装是一种信息隐藏技术,在java中通过关键字private实现封装。什么是封装?封装把对象的所有组成部分组合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。

    比如我们把一个学生的姓名 ,性别,年龄,以及其所具有的一些方法封装为一个学生实体,并对外提供一些接口,即使一种封装。通常我们所写的类,就是对一些具有相同事物的属性及方法的抽象,最后封装在一起。下面通过一个对图片类的封装,来进一步理解封装。封装之后的图片类,可以任意的在窗体上移动,改变大小,移动的速度这些都可以实现。

    package com.sg.PictureWatch;
    
    import java.awt.Graphics;
    import java.awt.Image;
    
    import javax.swing.ImageIcon;
    
    public class PictureWatch {
           Image img;
                /**
                  *图片的起始位置x,y
                  *图片的宽高
                  *图片在x,y方向上移动的速度
                  **/
           int x,y,width,height,Xspeed,Yspeed;
                //最少只需要传入一张图片路径即可
           public PictureWatch(String path)
             {
               this(path,0,0);
             }
           public PictureWatch(String path,int x,int y)
             {
              this(path,x,y,new ImageIcon(path).getIconWidth(),new ImageIcon(path).getIconHeight());
             }
           public PictureWatch(String path,int x,int y,int width,int height)
             {
               this(path,x,y,width,height,2,2);
             }
           public PictureWatch(String path,int x,int y,int width,int heighth,int Xspeed,int Yspeed)
             {
              img=new ImageIcon(path).getImage();
              this.x=x;
              this.y=y;
              this.width=width;
              this.height=height;
              this.Xspeed=Xspeed;
              this.Yspeed=Yspeed;
             }
                    //将图片画出来
             public void draw(Graphics g){
                 g.drawImage(img, x, y, width,height,null);
             }
              public void move(int xAdd, int yAdd, int times, boolean needWait) {
                 moveAndChange(xAdd, yAdd, 0, 0, times, needWait);
             }
    
             public void change(int wAdd, int hAdd, int times, boolean needWait) {
                 moveAndChange(0, 0, wAdd, hAdd, times, needWait);
             }
    
             public void moveAndChangeTo(int xAdd, int yAdd, int wAdd, int hAdd, int times, boolean needWait) {
                 moveAndChange(xAdd - x, yAdd - y, wAdd - width, hAdd - height, times, needWait);
             }
    
             public void moveAndChange(int xAdd, int yAdd, int wAdd, int hAdd, int times, boolean needWait) {
    
                 Object o = needWait ? new Object() : null;
    
                 new Thread() {
                     public void run() {
                         int xs = xAdd / times;
                         int ys = yAdd / times;
                         int ws = wAdd / times;
                         int hs = hAdd / times;
    
                         for (int i = 0; i < times; i++) {
                             x += xs;
                             y += ys;
                             width += ws;
                             height += hs;
                             isleep(30);
                         }
    
                         if (needWait) {
                             synchronized (o) {
                                 o.notify();
                             }
                         }
    
                     };
                 }.start();
    
                 if (needWait) {
                     synchronized (o) {
                         try {
                             o.wait();
                         } catch (InterruptedException e) {
                             // TODO Auto-generated catch block
                             e.printStackTrace();
                         }
                     }
                 }
    
             }
    
             private void isleep(int i) {
                 // TODO Auto-generated method stub
                 try {
                     Thread.currentThread().sleep(30);
                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             }
           
    }
    
    
    
    这里在创建图片的时候,最少就可以直接给一个图片的路径即可,或者给其他的参数,包括x,y的位置,宽高等。

    在图片移动的过程中,通过对象先用相应的move,change方法,可以发现这样用起来更加的方便。

    通过封装,不仅在使用的使用更加的方便,而且使我们的代码的逻辑更加强大。所以,能够轻松正确使用封装,是我们能否写出漂亮代码的第一步。






    展开全文
  • 首先,我们来封装特性。封装也叫作信息隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式(或者叫函数)来访问内部信息或者数据。这句话怎么理解呢?我们通过一个简单的例子来解释...

    封装(Encapsulation)

    首先,我们来看封装特性。封装也叫作信息隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式(或者叫函数)来访问内部信息或者数据。这句话怎么理解呢?我们通过一个简单的例子来解释一下。

    下面这段代码是金融系统中一个简化版的虚拟钱包的代码实现。在金融系统中,我们会给每个用户创建一个虚拟钱包,用来记录用户在我们的系统中的虚拟货币量。对于虚拟钱包的业务背景,这里你只需要简单了解一下即可。在面向对象的实战篇中,我们会有单独两节课,利用OOP的设计思想来详细介绍虚拟钱包的设计实现。

    抽象(Abstraction)

    讲完了封装特性,我们再来看抽象特性。 封装主要讲的是如何隐藏信息、保护数据,而抽象讲的是如何隐藏方法的具体实现,让调用者只需要关心方法提供了哪些功能,并不需要知道这些功能是如何实现的。

    在面向对象编程中,我们常借助编程语言提供的接口类(比如Java中的interface关键字语法)或者抽象类(比如Java中的abstract关键字语法)这两种语法机制,来实现抽象这一特性。

    这里我稍微说明一下,在专栏中,我们把编程语言提供的接口语法叫作“接口类”而不是“接口”。之所以这么做,是因为“接口”这个词太泛化,可以指好多概念,比如API接口等,所以,我们用“接口类”特指编程语言提供的接口语法。

    继承(Inheritance)

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

    为了实现继承这个特性,编程语言需要提供特殊的语法机制来支持,比如Java使用extends关键字来实现继承,C++使用冒号(class B : public A),Python使用paraentheses(),Ruby使用<。不过,有些编程语言只支持单继承,不支持多重继承,比如Java、PHP、C#、Ruby等,而有些编程语言既支持单重继承,也支持多重继承,比如C++、Python、Perl等。

    为什么有些语言支持多重继承,有些语言不支持呢?这个问题留给你自己去研究,你可以针对你熟悉的编程语言,在留言区写一写具体的原因。

    多态(Polymorphism)

    学习完了封装、抽象、继承之后,我们再来看面向对象编程的最后一个特性,多态。多态是指,子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现。

     

    • 1.关于封装特性

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

    • 2.关于抽象特性

    封装主要讲如何隐藏信息、保护数据,那抽象就是讲如何隐藏方法的具体实现,让使用者只需要关心方法提供了哪些功能,不需要知道这些功能是如何实现的。抽象可以通过接口类或者抽象类来实现,但也并不需要特殊的语法机制来支持。抽象存在的意义,一方面是提高代码的可扩展性、维护性,修改实现不需要改变定义,减少代码的改动范围;另一方面,它也是处理复杂系统的有效手段,能有效地过滤掉不必要关注的信息。

    • 3.关于继承特性

    继承是用来表示类之间的is-a关系,分为两种模式:单继承和多继承。单继承表示一个子类只继承一个父类,多继承表示一个子类可以继承多个父类。为了实现继承这个特性,编程语言需要提供特殊的语法机制来支持。继承主要是用来解决代码复用的问题。

    • 4.关于多态特性

    多态是指子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现。多态这种特性也需要编程语言提供特殊的语法机制来实现,比如继承、接口类、duck-typing。多态可以提高代码的扩展性和复用性,是很多设计模式、设计原则、编程技巧的代码实现基础。

    展开全文
  • 一、Java的三大特性(封装,继承,多态)a) 封装 面向对象程式设计中,封装(Encapsulation)就是把类的内部与外界隔离起来,把实现数据和方法的包装(隐藏),防止该类的代码和数据被外部类定义的代码随机访问。...

    一、Java的三大特性(封装,继承,多态)

    a) 封装

            面向对象程式设计中,封装(Encapsulation)就是把类的内部与外界隔离起来,把实现数据和方法的包装(隐藏),防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过特定的方式。

            举个例子,你现在在用电脑(手机)看这篇文章,然而你在使用电脑(手机)的时候并不需要理解电脑(手机)内部是怎么样构成的,你只需要对其作出输入(点击)就可以了。相当于黑箱(百度百科:黑箱理论

    封装的好处:

    1.  因为内部的数据方法等全部被隐藏隔离起来,外部只能对其做有限的访问,提高了安全性。

    2.  提高程序维护性,开发者只要保证其外部特征不变(输入输出等与外部的交互方式不变)就可以随便的修改和维护内部的程序结构和逻辑。

    例如,你写了一个类,向类的对象输入XY,实现X+Y的运算,你内部的运算逻辑是X*1+Y(当然不会有人这么写,例子而已);这时你写了另外一个类(外部)引用了前面那个类的对象并传入X=1Y=1,这时输出为2;这时你发现你写的第一个类可以改进,你把X*1+Y改成了X+Y,此时这个类已经被改动了,但是其外部特征还是没有变,还是输入XY,输入X+Y,所以外部类对其的引用不会受到影响。

    3. 提高了代码的复用性(模块化);如上例子,你可以在调用了该类的情况下,随时使用实现加法运行,不需要重新写其类内部的所有代码。

    b) 继承

            继承是所有OOP语言和Java语言不可缺少的部分。当创建一个类时,总是在继承,除非已经明确声明继承某个类,不然默认继承Java的标准根类Object。

            继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

            如:鸟都有翅膀等。鹰、麻雀、蜂鸟都是鸟类,它们就有鸟的特征,有翅膀等,那么就可以说鸟是父类,而鹰、麻雀、蜂鸟都是继承了鸟这个父类的子类。

     

    继承的声明是通过 extends 关键字声明,如下:

    class 父类 {}

    class 子类 extends 父类{ }

     

    这里需要注意的是:

    1.  在Java中,只支持单继承,如果实现多继承的功能可以采用接口以及对内部类的使用。

    2.  子类拥有父类非private的属性,方法。(private是父类私有的)

    3.  子类可以拥有自己的属性和方法。(如上面例子中,鹰有“食肉”这个自己的属性等)

    4.  提高了类之间的关系(子类与父类之间)。对比封装的说明,封装似乎是降低类之间的关系,更加模块化,而继承带来无法避免的小缺点是提高了类之间的关系。


    super关键字

    说到继承,就一定要简单提下super关键字。

    在子类中可以用super(),super.方法,super.变量名和对象名。

    super():调用父类构造方法(构造方法在下文有介绍)。

    super.方法名:直接访问并调用父类中的某个方法。

    super.变量名和对象名:直接访问父类中的变量或对象。

     

    c)  多态

            其实在上文描述继承的时候,就有多态的体现了,鸟类的子类却有多种形态,这就是多态的表现。

    可见,继承是多态的条件之一,而多态的另外两个条件:Override(重写、覆盖)、父类引用可以指向子类对象。

    1.  Override(重写、覆盖)

    父类中允许被继承的方法在子类中被重新编写。方法名、返回值和参数都不能变化,被重新编写的是方法内部。

    如下,eat就被重写了

    class父类 {

    public void eat(){

    System.out.println(“吃两碗饭”);

    }

    }

    class 子类 extends 父类{

    public void eat(){

    System.out.println(“吃一碗饭”);

    }

    public void run(){

    System.out.println(“跑步”);

    }

    }

    2.  父类引用可以指向子类对象

            子类继承父类之后,子类相当于对其做了扩充改进,但是父类和子类之间是存在共性。所以定义父类类型的引用指向子类,即父类 父类对象 = new 子类构造方法(子类对象),而这个引用只能调用父类中定义的方法和变量,如果子类重写了父类的方法,那么父类调用这个方法时,将会调用重写后的方法,不能调用子类自己独有的方法。

     

    多态的体现主要有两个方面:1、方法的重载和重写。2、对象的多态性。

    1. 方法的重载在构造函数介绍中已经说明,而重写在上文有介绍。

    2. 对象的多态性

    对象的多态性主要体现在:

    a)对象向上转型:子类转为父类,如上文中的父类引用指向子类对象,

                 即 父类 父类对象 = 子类对象

    b)对象向下转型:父类转为子类,即子类 子类对象 = (子类)父类对象,这个过程需要强转。

    多态的优点:1.可替换性(重写)2.可扩充性(子类拥有自己的方法)3.接口性(向子类提供了相同的接口,由子类完善)4.灵活性(实现多样化的操作)5.简化性(提高代码复用性,简化了编写过程)

     

    二、 抽象(abstract)

    由abstract修饰的类和方法,称为抽象类和抽象方法。

            抽象可以理解为是一个概念,不可以用一个具体的实例来描述,其实现必须由子类和子类的重写来实现。引用上面鸟类的例子,如我们定义鸟类为父类,那么鸟类会叫会吃,但是叫是怎么叫什么声音的叫,吃是吃什么,并没有说明,只是一个抽象的笼统的说明,也无法创建一个实例。那我们就可以把鸟类成为抽象类,其中的叫和吃为抽象方法。例程如下:

    public abstract class Bird{

    public abstract String voice();

    public abstract Stringeat();

    public Booleanfly(){}

    }

    1. 抽象类

    如上例程,可以知道使用abstract修饰类来定义一个抽象类。

    抽象类的特点:

    1.抽象类不能直接实例化,必须依靠子类来实例化。

    2.抽象类必须有子类,不然抽象类没有意义,而且一个子类只能继承一个抽象类。

    3.子类必须重写抽象类中的所有抽象方法

    4.抽象类中也可以存在非抽象方法、也可以不包含抽象方法

     

    2. 抽象方法

    如上例程,可以知道使用abstract修饰方法来定义一个抽象方法。

    抽象方法的特点:

    1一个类包含抽象方法,那么这个类一定是抽象类。

    2子类必须重写父类的抽象方法,或者声明自身也是抽象类。

    3抽象类中的抽象方法只是声明,并不存在具体方法体。

    4构造方法、static修饰的方法不能定义为抽象方法。


    转载地址 https://blog.csdn.net/Rany_w/article/details/79879449

    展开全文
  • 一、Java的三大特性(封装,继承,多态)a) 封装 面向对象程式设计中,封装(Encapsulation)就是把类的内部与外界隔离起来,把实现数据和方法的包装(隐藏),防止该类的代码和数据被外部类定义的代码随机访问。...
  • 我们先来封装的特性 我们首先要了解它的概念是不,我们来看看它的概念 封装的概念 将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问。 封装的好处 (1...
  • ——犹达(Yoda)在修复软件缺陷的各个阶段,程序员的态度从拒绝到开明再到怀疑到的发展过程:那种问题不可能出现我的机器上没有出现过这种问题那种问题不应该出现怎么会发生那种问题噢,我看看以前怎么运行正常呢?...
  • 新手必编程法则C++

    2009-04-18 07:08:12
    7.5 free和delete把指针怎么啦? 7.6 动态内存会被自动释放吗? 7.7 杜绝“野指针” 7.8 有了malloc/free为什么还要new/delete ? 7.9 内存耗尽怎么办? 7.10 malloc/free 的使用要点 7.11 new/delete 的使用要点 ...
  • -在AJAX回发后确保Asp.net的按钮控件仍然具有AJAX的特性。 -更新/basic/login.aspx示例,使用验证图片(feedback:kedee)。 -为Grid增加AutoPostBack属性和RowClick事件,示例在/data/grid_autopostback.aspx...
  • JavaScript中的私有成员

    2020-12-09 14:13:40
    JavaScript对象可以拥有私有成员,下面我们来看看怎么做。(SharkUI.com注:JavaScript并不是真正拥有私有、公有等等OOP的特性,这篇译文中提到的这些私有、公有、特权等特性,是利用JavaScript的其他特性(参看本文...
  • 如果图片不到可以参考: https://blog.csdn.net/lkx444368875/article/details/80407893 功能展示 注解使用 入参 1.1 多层级的入参 出参 ​ 多层级出参 : 调试 特殊特性 支持Model中的属性特殊...
  • JDBC以一种统一的方式来对各种各样的数据库进行存取,JDBC为开发人员隐藏了不同数据库的不同特性。程序员开发时,知道要开发访问数据库的应用,于是将一个对应数据库的JDBC驱动程序类的引用进行了编码,并通过使用...
  • 首先,我们来封装特性。封装也叫作信息隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式(或者叫函数)来访问内部信息或者数据。这句话怎么理解呢?我们通过一个简单的例子来解释...
  • 封装: 面向对象的三个基本特征(封装、继承、多态)之一。将现实世界的事物抽象成计算机领域中的对象,具有属性...**重要特性:**数据隐藏。正常交互+安全性(“不要告诉我你是怎么做的,做就行。”) 详:JavaS...
  • 面向对象编程有三大特性:封装、继承、多态。 封装的引入 我要电视,只需要按一下开关和换台就可以了。有必要了解电视机内部的结构吗?有必要碰碰显像管吗?制造厂家为了方便我们使用电视,把复杂的内部细节全部...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 160
精华内容 64
关键字:

隐藏特性怎么看