收藏 分享(赏)

java面向对象整理.doc

上传人:hskm5268 文档编号:6620672 上传时间:2019-04-18 格式:DOC 页数:15 大小:80.50KB
下载 相关 举报
java面向对象整理.doc_第1页
第1页 / 共15页
java面向对象整理.doc_第2页
第2页 / 共15页
java面向对象整理.doc_第3页
第3页 / 共15页
java面向对象整理.doc_第4页
第4页 / 共15页
java面向对象整理.doc_第5页
第5页 / 共15页
点击查看更多>>
资源描述

1、java 中重载与重写的区别重载(Overloading)(1) 方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载 Overloading 是一个类中多态性的一种表现。(2) Java 的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性。(3) 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。下面是重载的例子:package c04.ans

2、wer;/这是包名/这是这个程序的第一种编程方法,在 main 方法中先创建一个 Dog 类实例,然后在 Dog 类的构造方法中利用 this 关键字调用不同的 bark 方法。不同的重载方法 bark 是根据其参数类型的不同而区分的。/注意:除构造器以外,编译器禁止在其他任何地方中调用构造器。package c04.answer;public class Dog Dog()this.bark();void bark()/bark()方法是重载方法System.out.println(“no barking!“);this.bark(“female“, 3.4);void bark(Strin

3、g m,double l)/注意:重载的方法的返回值都是一样的,System.out.println(“a barking dog!“);this.bark(5, “China“);void bark(int a,String n)/不能以返回值区分重载方法,而只能以“参数类型”和“类名”来区分System.out.println(“a howling dog“);public static void main(String args)Dog dog = new Dog();/dog.bark(); Page/dog.bark(“male“, “yellow“);/dog.bark(5, “C

4、hina“);重写(Overriding)(1) 父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在 Java 中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。(2)若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用 super 关键字,该关键字引用了当前类的父类。(3)子类函数的访问修饰权限不能少于父类的;下面

5、是重写的例子:概念:即调用对象方法的机制。动态绑定的内幕:1、编译器检查对象声明的类型和方法名,从而获取所有候选方法。试着把上例 Base 类的 test注释掉,这时再编译就无法通过。2、重载决策:编译器检查方法调用的参数类型,从上述候选方法选出唯一的那一个(其间会有隐含类型转化)。如果编译器找到多于一个或者没找到,此时编译器就会报错。试着把上例 Base 类的 test(byte b)注释掉,这时运行结果是 1 1。3、若方法类型为 priavte static final ,java 采用静态编译,编译器会准确知道该调用哪个方法。4、当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必

6、须调用对象的实际类型相匹配的方法版本。在例子中,b 所指向的实际类型是 TestOverriding,所以 b.test(0)调用子类的 test。但是,子类并没有重写 test(byte b),所以 b.test(byte)0)调用的是父类的 test(byte b)。如果把父类的(byte b)注释掉,则通过第二步隐含类型转化为 int,最终调用的是子类的 test(int i)。学习总结:多态性是面向对象编程的一种特性,和方法无关,简单说,就是同样的一个方法能够根据输入数据的不同,做出不同的处理,即方法的重载有不同的参数列表(静态多态性)而当子类继承自父类的相同方法,输入数据一样,但要做

7、出有别于父类的响应时,你就要覆盖父类方法,即在子类中重写该方法相同参数,不同实现(动态多态性)OOP 三大特性:继承,多态,封装。public class Basevoid test(int i)System.out.print(i);void test(byte b)System.out.print(b);public class TestOverriding extends Basevoid test(int i)i+;System.out.println(i);public static void main(Stringagrs)Base b=new TestOverriding();b

8、.test(0)b.test(byte)0)这时的输出结果是 1 0,这是运行时动态绑定的结果。重写的主要优点是能够定义某个子类特有的特征:public class Fatherpublic void speak()System.out.println(Father);public class Son extends Fatherpublic void speak()System.out.println(“son“);这也叫做多态性,重写方法只能存在于具有继承关系中,重写方法只能重写父类非私有的方法。当上例中 Father 类 speak()方法被 private 时,Son 类不能重写出 F

9、ather 类 speak()方法,此时Son 类 speak()方法相当与在 Son 类中定义的一个 speak()方法。Father 类 speak()方法一但被 final 时,无论该方法被 public,protected 及默认所修饰时,Son 类根本不能重写 Father 类 speak()方法,试图编译代码时,编译器会报错。例:public class Fatherfinal public void speak()System.out.println(“Father“);public class Son extends Fatherpublic void speak()Syste

10、m.out.println(“son“); /编译器会报错;Father 类 speak()方法被默认修饰时,只能在同一包中,被其子类被重写,如果不在同一包则不能重写。Father 类 speak()方法被 protoeted 时,不仅在同一包中,被其子类被重写,还可以不同包的子类重写。重写方法的规则:1、参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。2、返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。3、访问修饰符的限制一定要大于被重写方法的访问修饰符(publicprotecteddefaultprivate)4、重写方法一定不能抛出新的检查异

11、常或者比被重写方法申明更加宽泛的检查型异常。例如:父类的一个方法申明了一个检查异常 IOException,在重写这个方法是就不能抛出 Exception,只能抛出 IOException 的子类异常,可以抛出非检查异常。而重载的规则:1、必须具有不同的参数列表;2、可以有不责骂的返回类型,只要参数列表不同就可以了;3、可以有不同的访问修饰符;4、可以抛出不同的异常;重写与重载的区别在于:重写多态性起作用,对调用被重载过的方法可以大大减少代码的输入量,同一个方法名只要往里面传递不同的参数就可以拥有不同的功能或返回值。用好重写和重载可以设计一个结构清晰而简洁的类,可以说重写和重载在编写代码过程中

12、的作用非同一般.Java 关键字 this、super 使用总结一、thisJava 关键字 this 只能用于方法方法体内。当一个对象创建后, Java 虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是 this。因此,this 只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现 this,这在“Java 关键字 static、final 使用总结”一文中给出了明确解释。并且 this 只和特定的对象关联,而不和类关联,同一个类的不同对象有不同的 this。下面给出一个使用 this 的综合实例,以便说明问题:package org.leizhimin

13、;public class Test6 private int number;private String username;private String password;private int x = 100;public Test6(int n) number = n; / 这个还可以写为: this.number=n;public Test6(int i, String username, String password) / 成员变量和参数同名,成员变量被屏蔽,用“this. 成员变量“的方式访问成员变量.this.username = username;this.password

14、= password;/ 默认不带参数的构造方法public Test6() this(0, “未知“, “空“); / 通过 this 调用另一个构造方法public Test6(String name) this(1, name, “空“); / 通过 this 调用另一个构造方法public static void main(String args) Test6 t1 = new Test6();Test6 t2 = new Test6(“游客“);t1.outinfo(t1);t2.outinfo(t2);private void outinfo(Test6 t) System.out

15、.println(“-“);System.out.println(t.number);System.out.println(t.username);System.out.println(t.password);f(); / 这个可以写为: this.f();private void f() / 局部变量与成员变量同名,成员变量被屏蔽,用“this. 成员变量 “的方式访问成员变量.int x;x = this.x+;System.out.println(x);System.out.println(this.x);/返回当前实例的引用private Test6 getSelf() return

16、this; 运行结果如下:-0未知空100101-0游客空100101看着上面的例子,说明在什么情况下需要用到 this:第一、通过 this 调用另一个构造方法,用发是 this(参数列表),这个仅仅在类的构造方法中,别的地方不能这么用。第二、函数参数或者函数中的局部变量和成员变量同名的情况下,成员变量被屏蔽,此时要访问成员变量则需要用“this.成员变量名 ”的方式来引用成员变量。当然,在没有同名的情况下,可以直接用成员变量的名字,而不用 this,用了也不为错,呵呵。第三、在函数中,需要引用该函所属类的当前对象时候,直接用 this。其实这些用法总结都是从对“this 是指向对象本身的一

17、个指针” 这句话的更深入的理解而来的,死记不然容易忘记而且容易搞错,要理解!二、supersuper 关键和 this 作用类似,是被屏蔽的成员变量或者成员方法或变为可见,或者说用来引用被屏蔽的成员变量和成员成员方法。不过 super 是用在子类中,目的是访问直接父类中被屏蔽的成员,注意是直接父类(就是类之上最近的超类)。下面是一个综合运用 super 的例子,有两个类:一个 Father 类,一个 Father 类的子类 Son,通过这两个类完全演示了 super 的用法,一下是代码:package org.leizhimin;public class Father public Strin

18、g v=“Father“;public String x=“输出了 Father 类的 public 成员变量 x!“;public Father() System.out.println(“Father 构造方法被调用!“);public Father(String v)this.v=“Father 类的带参数构造方法!运行了.“;public void outinfo()System.out.println(“Father 的 outinfo 方法被调用“); public static void main(String args) / TODO 自动生成方法存根package org.l

19、eizhimin;public class Son extends Fatherpublic String v=“Son“;public Son() super(); /调用超类的构造方法, 只能放到第一行.System.out.println(“Son 无参数构造方法被调用 !“);/super(); /错误的,必须放到构造方法体的最前面 . public Son(String str)super(str);System.out.println(“Son 带参数构造方法被调用 !“);/覆盖了超类成员方法 outinfo()public void outinfo() System.out.p

20、rintln(“Son 的 outinfo()方法被调用“); public void test()String v=“哈哈哈哈!“; /局部变量 v 覆盖了成员变量 v 和超类变量 vSystem.out.println(“-1-“);System.out.println(v); /输出局部变量 vSystem.out.println(this.v); /输出(子类) 成员变量 vSystem.out.println(super.v); /输出超类成员变量 v System.out.println(“-2-“);System.out.println(x); /输出超类成员变量 v,子类继承而

21、来System.out.println(super.x); /输出超类成员变量 vSystem.out.println(“-3-“);outinfo(); /调用子类的 outinfo()方法this.outinfo(); /调用子类的 outinfo()方法super.outinfo(); /调用父类的 outinfo()方法 public static void main(String args) new Son().test();子类 Son 运行结果:Father 构造方法被调用 !Son 无参数构造方法被调用!-1-哈哈哈哈!SonFather-2-输出了 Father 类的 pub

22、lic 成员变量 x!输出了 Father 类的 public 成员变量 x!-3-Son 的 outinfo()方法被调用Son 的 outinfo()方法被调用Father 的 outinfo 方法被调用说明:次例子仅仅为了说明 super 的用法,实际在设计类的时候一般都尽可能私有(private) 化。通过上面的例子,下面总结一下 super 的用法:第一、在子类构造方法中要调用父类的构造方法,用“super(参数列表)” 的方式调用,参数不是必须的。同时还要注意的一点是:“super(参数列表)”这条语句只能用在子类构造方法体中的第一行。第二、当子类方法中的局部变量或者子类的成员变量

23、与父类成员变量同名时,也就是子类局部变量覆盖父类成员变量时,用“super.成员变量名”来引用父类成员变量。当然,如果父类的成员变量没有被覆盖,也可以用“super.成员变量名”来引用父类成员变量,不过这是不必要的。第三、当子类的成员方法覆盖了父类的成员方法时,也就是子类和父类有完全相同的方法定义(但方法体可以不同),此时,用“super.方法名(参数列表)”的方式访问父类的方法。this、super 的用法也不过这些,只有理解了其中的原理,才不会跌入陷阱!Java 中 abstract class 和 interface 的解释和他们的异同点 (一)概述在 Java 语言中, abstrac

24、t class 和 interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了 Java 强大的 面向对象能力。abstract class 和 interface 之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进 行抽象类定义时对于 abstract class 和 interface 的选择显得比较随意。其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对 于问题领域本质的理解、对于设计意图的理解是否正确、合理。abstract class 和 interface 在 Java 语言中都是用来进行抽象类(本文 中的抽象类并

25、非从abstract class 翻译而来,它表示的是一个抽象体,而 abstract class 为 Java 语言中用于定义抽象类的一种方法, 请读者注意区分)定义的,那么什么是抽象类,使用抽象类能为我们带来什么好处呢?在 面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是 所有的类都是用来描绘对象的(把类具体化),如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、 设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。比如:如果我们进行一个图形编辑软件的开发,就会发现

26、问题领域存在着圆、 三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念 在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。在面向对象领域,抽象类主要用来进行类型隐藏。 我们可以构造出一个固定的一组行为的抽象描 述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。好比,动物是一个抽象类,人、猴子、老虎就是具体实现的派生类,我们就可以用动物类型来隐藏人、猴子和老虎的类型。(二)从语法定义来分析在语法层面,

27、Java 语言对于 abstract class 和 interface 给出了不同的定义方式,下面以定义一个名为 Demo 的抽象类为例来说明这种不同。使用 abstract class 的方式定义 Demo 抽象类的方式如下:abstract class Demoabstract void method1();abstract void method2();使用 interface 的方式定义 Demo 抽象类的方式如下:interface Demovoid method1();void method2();在 abstract class 方式中,Demo 可以有自己的数据成员,也可以有

28、非 abstract 的成员方法,而在 interface 方式的实现中,Demo 只能够有静态的不能被修改的数据成员(也就是必须是static final 的,不过在 interface 中一般不定义数据成员),所有的成员方法都是 abstract 的。从某种意义上说,interface 是一种特殊形式的 abstract class。从编程的角度来看,abstract class 和 interface 都可以用来实现 “design by contract“ 的思想。但是在具体的使用上面还是有一些区别的。首先,abstract class 在 Java 语言中表示的是一种继承关系,一个类

29、只能使用一次继承关系(因为 Java 不支持多继承 - 转注)。但是,一个类却可以实现多个 interface。也许,这是 Java语言的设计者在考虑 Java 对于多重继承的支持方面的一种折中考虑吧。其次,在 abstract class 的定义中,我们可以赋予方法的默认行为。但是在 interface 的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会增加一些复杂性,有时会造成很大的麻烦。在 抽象类中不能定义默认行为还存在另一个比较严重的问题,那就是可能会造成维护上的麻烦。因为如果后来想修改类的界面(一般通过 abstract class 或者 interface

30、来表示)以适应新的情况(比如,添加新的方法或者给已用的方法中添 加新的参数)时,就会非常的麻烦,可能要花费很多的时间(对于派生类很多的情况,尤为如此)。但是如果界面是通过 abstract class 来实现的,那 么可能就只需要修改定义在 abstract class 中的默认行为就可以了。同样,如果不能在抽象类中定义默认行为,就会导致同样的方法实现出现在该抽象类的每一个派生类中,违反了 “one rule,one place“原则,造成代码重复,同样不利于以后的维护。因此,在 abstract class 和 interface 间进行选择时要非常的小心。(三)从设计理念层面分析上面主要从

31、语法定义和编程的角度论述了 abstract class 和 interface 的区 别,这些层面的区别是比较低层次的、非本质的。本小节将从另一个层面:abstract class 和 interface 所反映出的设计理念,来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概念的本质所在。前面已经提到过,abstract class 在 Java 语言中体现了一种继承关系,要想使得 继承关系合理,父类和派生类之间必须存在“is-a“关系,即父类和派生类在概念本质上应该是相同的。对于interface 来说则不然,并不要求 interface 的实现者和 interface 定义

32、在概念本质上是一致的, 仅仅是实现了 interface 定义的契约而已。为了使论述便于理解,下面将通过一个简单的实例进行说明。考虑这样一个例子,假设在我们的问题领域中有一个关于 Door 的抽象概念,该 Door 具有执行两个动作 open 和 close,此时我们可以通过 abstract class 或者 interface 来定义一个表示该抽象概念的类型,定义方式分别如下所示:使用 abstract class 方式定义 Door:abstract class Doorabstract void open();abstract void close();使用 interface 方式定

33、义 Door:interface Doorvoid open();void close();其他具体的 Door 类型可以 extends 使用 abstract class 方式定义的 Door 或者implements 使用 interface 方式定义的 Door。看起来好像使用 abstract class 和 interface 没有大的区别。如果现在要求 Door 还要具有报警的功能。我们该如何设计针对该例子的类结构呢(在本例中,主要是为了展示 abstract class 和 interface 反映在设计理念上的区别,其他方面无关的问题都做了简化或者忽略)?下面将罗列出可能的解

34、 决方案,并从设计理念层面对这些不同的方案进行分析。解决方案一:简单的在 Door 的定义中增加一个 alarm 方法,如下:abstract class Doorabstract void open();abstract void close();abstract void alarm();或者interface Doorvoid open();void close();void alarm();那么具有报警功能的 AlarmDoor 的定义方式如下:class AlarmDoor extends Doorvoid open()void close()void alarm()或者class

35、AlarmDoor implements Doorvoid open()void close()void alarm()这种方法违反了面向对象设计中的一个核心原则 ISP (Interface Segregation Principle),在 Door 的定义中把 Door 概念本身固有的行为方法和另外一个概念“报警器“ 的行为方 法混在了一起。这样引起的一个问题是那些仅仅依赖于 Door 这个概念的模块会因为“报警器“ 这个概念的改变(比如:修改 alarm 方法的参数)而改变,反 之依然。解决方案二:既然 open、close 和 alarm 属于两个不同的概念,根据 ISP 原则应该把它

36、们分别定 义在代表这两个概念的抽象类中。定义方式有:这两个概念都使用 abstract class 方式定义;两个概念都使用 interface 方式定义;一个概念 使用 abstract class 方式定义,另一个概念使用 interface方式定义。显然,由于 Java 语言不支持多重继承,所以两个概念都使用 abstract class 方式定义是不可行的。后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。我们一一来分析、说明。如果两个概念都使用 interface 方式来定义,那么就反映出两个问题:1、我们可能没有 理

37、解清楚问题领域,AlarmDoor 在概念本质上到底是 Door 还是报警器?2、如果我们对于问题领域的理解没有问题,比如:我们通过对于问题领域的分 析发现 AlarmDoor 在概念本质上和 Door 是一致的,那么我们在实现时就没有能够正确的揭示我们的设计意图,因为在这两个概念的定义上(均使用 interface 方式定义)反映不出上述含义。如果我们对于问题领域的理解是:AlarmDoor 在概念本质上是 Door,同时它有具有报 警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,abstract class 在Java 语言中表示一种继承关系,而继承关系 在本质上

38、是“is-a“ 关系。所以对于 Door 这个概念,我们应该使用 abstarct class 方式来定义。另外,AlarmDoor 又具有报警功能,说 明它又能够完成报警概念中定义的行为,所以报警概念可以通过 interface 方式定义。如下所示:abstract class Doorabstract void open();abstract void close();interface Alarmvoid alarm();class Alarm Door extends Door implements Alarmvoid open()void close()void alarm()这种实

39、现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其 实 abstract class 表示的是“is-a“关系,interface 表示的是“like-a“ 关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为 AlarmDoor 在概念本质上是报警器,同时又具有 Door 的功能,那么上述的定义方式就要反过来了。(四)abstract class 总结1.abstract class 通常含有一个或多个抽象方法,抽象方法不提供实现;包含抽象方法的类必须声明为抽象类 abstract class;abstract class

40、的所有具体子类都必须为超类提供具体实现;子类如果没有实现超类的抽象方法,则会产生编译错误,除非子类也声明为 abstract。2.abstract class 声明了类层次结构中各个类的共同属性和行为;由于不能继承构造函数,因此构造函数不能声明为抽象方法;尽管不能实例化抽象类的对象,但是能够声明抽象类型的变量,这种变量可用于引用子类的对象(五)interface 总结1.接口以 interface 开始,并包含一组默认为是 public 的抽象方法,接口可以包含变量,默认为 static final 的,且必须给其初值,所以实现类中不能重新定义,也不能改变其值;实现接口必须实现其中的所有方法,

41、接口中不能有实现方法,所有的成员方法都是 abstract 的。2.如果一个类没有实现任何接口方法,则它是抽象类,并且必须以关键字 abstract 声明该类;实现一个接口如同与编译器达成一个协议,“我将声明该接口制定的所有方法” 。(六)小结1.abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个 interface。2. 在 abstract class 中可以有自己的数据成员,也可以有非 abstarct 的成员方法,而在interface 中,只能够有静态的不能被修改的数据成员(也就是必须是 static fin

42、al 的,不过在 interface 中一般不定义数据成员),所有的成员方法都是 abstract 的。3.abstract class 和 interface 所反映出的设计理念不同。其实 abstract class 表示的是“is-a“关系,interface 表示的是“like-a“关系。4.接口一般用于在抽象类中没有可供继承的默认实现时(即没有实例变量和默认方法实现)代替该类。5.abstract class 是另一种契约形式,是设计对实现的要求;而接口是服务器对客户端的要求。6.abstract class 是一个基类,不能被实例化;接口是个声明,每个对应接口的类都要实现方法。7.

43、 一个子类如果 implements 一个接口,就必须实现接口中的所有方法(不管是否需要);如果是继承一个抽象类,只需要实现需要的方法即可,这是抽象类的一个优点8. 如果一个接口中定义的方法名改变了,那么所有实现此接口的子类显然将无法通过编译,因为它们所实现的方法名已经不存在了,这是接口的一个缺点;而抽象类中如果有个非抽象方法改了,就不存在这个问题,只是为子类添加了一个新的方法。9. 看前面两点,似乎抽象类要比接口有着更多的优点,但它却有着一个难以弥补的缺点:就是一个子类只能有一个父类。A extends B 。这样 A 就拥有了 B 的所有方法和功能,但当 A 还想拥有C 的功能的时候。就不能通过 A extends C 来实现,而需要走一些弯路。目前系统架构的趋势就是由针对抽象(借口,抽象类)而不是具体编程,并且将功能尽可能的细分。这就需要通过实现多个接口的方式来实现,显然,抽象类无法提供这样的功能。从系统重构的角度来说,一个具体类抽象出接口是十分方便的。只需要写一个接口,里面定义具体类的所有方法,然后在为这个具体类implement 这个接口就可以了。而抽象类就要复杂的多,比如说 B extends A , C extends B 如果想要为 c 抽象出一个抽象类 D 的话,就需要找到它的最顶层 A 来从头做起,因为无法做到 C extends D

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报