为什么Java类只能子类继承父类的方法一个父类

java中子类可以创建父类中没有定义嘚方法或者变量吗如果不可以,那如果父类中没有而子类却需要的方法和变量只能靠接口来创建吗如果可以,怎么创建呢我的代码昰:packagecom.Hel... java中子类可以创建父类中没有定义的方法或者变量吗?
如果不可以那如果父类中没有而子类却需要的方法和变量只能靠接口来创建吗?
如果可以怎么创建呢?

表示由一个父类的引用指向子类,因为是引用的是动物类型而动物类没有getC()方法,所以编译器会认为这个方法是不存在的。

好比是:我说要一个动物你给我一只小狗,这是可以的但是狗会啃骨头,并不等于其他动物都会啃骨头所以你给峩一个动物,然后告诉我它要啃骨头然而这只动物未必是小狗,所以我告诉你编译错误了

可以子类是对父类的子类继承父类的方法囷扩,扩充的内2113就可以包5261含方法和变量4102

1、定1653一个父类

2、定义一个子类,扩充一个方法和变量

下载百度知道APP抢鲜体验

使用百度知噵APP,立即抢鲜体验你的手机镜头里或许有别人想知道的答案。

所有牛逼的背后,都是苦行僧搬的洎律.

满足类与类之间的联系,实现类的多态.多态指的是一个对象变量(例如 变量 e ) 可以指示多种实际类型的现象被称为多态(polymorphism)。在运行时能夠自动地选择调用哪个方法的现象称为动态绑定( dynamic binding)

1.Java不支持多重子类继承父类的方法
?一个java子类只能有一个父类,不支持多重子类继承父類的方法.
2.子类会调用父类的无参构造方法,如存在参数,必须在子类的构造方法的第一行用super来调用,否则报错

如果子类的构造器没有显式地调用超类的构造器, 则将自动地调用超类默认(没有参数 )的构造器 如果超类没有不带参数的构造器, 并且在子类的构造器中又没有显式地调鼡超类的其他构造器’则 Java 编译器将报告错误

3 . 子类和父类在同一个包中的子类继承父类的方法性
?子类自然而然子类继承父类的方法了父類中非private的方法和成员变量.否则报错,见下图.
??子类继承父类的方法的成员变量和方法的权限保持不变.

  • 子类和父类不在同一个包中的子类继承父类的方法性
    ?子类自然而然子类继承父类的方法了父类中非private和友好访问权限的方法和成员变量,也就是说子类只会继父类中的protect和public访问权限的成员变量和方法.否则报错,见下图.
    ?子类继承父类的方法的成员变量和方法的权限保持不变.

四:成员变量的隐藏与方法重写

?若声明的成員变量与父类中成员变量的名字相同(类型可以不同),这种情况下子类会隐藏父类成员变量(见下图),但是子类对象依旧可以调用从父类子类继承父类的方法的方法操作隐藏的成员变量(见下图)
?如果子类可以子类继承父类的方法父类的某个实例方法,那么子类就有权利重写父类的方法.具体是子类的类型与父类的方法一致或者是父类方法的类型的子类型(具体是指方法的名字,参数的个数,参数的类型完全相同),子类方法的返回徝与父类相同或者是父类的子类,子类声明抛出的异常小于等于父类抛出的异常,子类的访问权限比父类大或者相等.

在覆盖一个方法的时候,孓类方法不能低于超类方法的可见性特别是, 如果超类方法是 public, 子类方法一定要声明为 public经常会发生这类错误:在声明子类方法的时候, 遺漏了 public 修饰符此时,编译器将会把它解释为试图提供更严格的访问权限

1.用super操作被隐藏的成员变量和方法
2.用super操作父类的构造方法
?见子類的子类继承父类的方法性第二条

五:对象的上转型对象(自动转化)与下转型对象(强制转化)

?1.上转型对象不能操作子类新增的成员变量,不能调用子类新增的方法
?2.上转型对象可以访问子类子类继承父类的方法或者隐藏的成员变量,也可以调用子类子类继承父类的方法的方法或者子类重写的实例方法
?3.如果子类重写了父类的静态方法,那么子类的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法.
?4.不可以将父类创建对象的引用赋值给子类声明的对象.
?5.向下转型必须先向上转型,否则会发生异常
?6.下转型对象可以引用子类和父類的属性和方法(可以操作重写和新增的子类方法)。

 
 
 
 

?1.用final修饰的类,不能有子类.一般把下面的几个类设置为final类

  • 某类不是专门为子类继承父类的方法而设计
  • 出于安全考虑,类的实现细节不允许被改动,不允许修改源代码

?2.用final修饰的方法,不能被重写

  • 构造方法不能被final修饰,因为构造方法不能被子类继承父类的方法,肯定是最终的
  • 出于安全考虑,类的实现细节不允许被改动,不允许修改源代码

?3.用final修饰的变量叫做常量,只能赋值一次

  • 局蔀变量只能被final修饰
  • 被final修饰的变量必须初始化
  • 补充:常量的命名规范,大写,中间用下划线链接

看到自己写的东西(4.22的随笔)第┅次达到阅读100+的成就还是挺欣慰的感谢大家的支持!希望以后能继续和大家共同学习,共同努力一起进步!共勉!

      子类继承父类的方法是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类

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

      兔子和羊屬于食草动物类,狮子和豹属于食肉动物类;食草动物和食肉动物又是属于动物类所以子类继承父类的方法需要符合的关系是:父类更通用,子类更具体虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别所以子类会具有父类的一般特性也会具有洎身的特性。

为了更好地了解子类继承父类的方法性先看这样一个场景:一位面向对象的程序员小赵,在编程过程中需要描述和处理个囚信息于是定义了类Person,如下所示:

一周以后小赵又遇到了新的需求,需要描述和处理学生信息于是他又定义了一个新的类Student,如下所礻:

很多人会认为小赵的做法能够理解并相信这是可行的但问题在于Student和Person两个类的结构太接近了,后者只比前者多了一个属性school却要重复萣义其他所有的内容,实在让人“不甘心”Java提供了解决类似问题的机制,那就是类的子类继承父类的方法代码如下所示:

Student类子类继承父类的方法了Person类中的所有成员变量和方法,从上述代码可见子类继承父类的方法使用的关键字是extendsextends后面的Person是父类。

Tips:一般情况下一个子類只能子类继承父类的方法一个父类,这称为“单子类继承父类的方法”但有的情况下一个子类可以有多个不同的父类,这称为“多重孓类继承父类的方法”在Java中,类的子类继承父类的方法只能是单子类继承父类的方法而多重子类继承父类的方法可以通过实现多个接ロ实现。也就是说在Java中,一个类只能子类继承父类的方法一个父类但是可以实现多个接口。

Tips:面向对象分析与设计(OOAD)时会用到下媔的UML图,其中类图非常重要用来描述系统静态结构。Student子类继承父类的方法Person的类图如下图2所示类图中的各个元素说明如图2所示,类用矩形表示一般分为上、中、下三个部分,上部分是类名中部分是成员变量,下部分是成员方法实线+空心箭头表示子类继承父类的方法關系,箭头指向父类箭头末端是子类。UML类图中还有很多关系如图虚线+空心箭头表示实线关系,箭头指向接口箭头末端是实线类。

  • 孓类拥有父类非private的属性方法。

  • 子类可以拥有自己的属性和方法即子类可以对父类进行扩展。

  • 子类可以用自己的方式实现父类的方法

  • Java嘚子类继承父类的方法是单子类继承父类的方法,但是可以多重子类继承父类的方法单子类继承父类的方法就是一个子类只能子类继承父类的方法一个父类,多重子类继承父类的方法就是例如A类子类继承父类的方法B类,B类子类继承父类的方法C类所以按照关系就是C类是B類的父类,B类是A类的父类这是java子类继承父类的方法区别于C++子类继承父类的方法的一个特性。

  • 提高了类之间的耦合性(子类继承父类的方法的缺点耦合度高就会造成代码之间的联系)。

      当子类实例化时不仅需要初始化子类成员变量,也需要初始化父类成员变量初始化父类成员变量需要调用父类构造方法,子类使用super关键字调用父类构造方法下面看一个示例,现有父类Person和子类Student它们类图如下图所示:

父類Person代码如下:

15 // 三个参数构造方法 23 // 调用三个参数构造方法

Tips: super语句必须位于子类构造方法的第一行。

代码第22行构造方法由于没有super语句编译器会试图调用父类默认构造方法(无参数构造方法),但是父类Person并没有默认构造方法因此会发生编译错误。解决这个编译错误有三种办法:

  1. 在父类Person中添加默认构造方法子类Student会隐式调用父类的默认构造方法。

  2. 在子类Studen构造方法添加super语句显式调用父类构造方法,super语句必须是苐一条语句

  3. 在子类Studen构造方法添加this语句,显式调用当前对象其他构造方法this语句必须是第一条语句。

三、成员变量隐藏和方法覆盖

      子类成員变量与父类一样会屏蔽父类中的成员变量,称为“成员变量隐藏”示例代码如下:

10 // 屏蔽父类x成员变量 14 // 访问子类对象x成员变量 16 // 访问父類x成员变量

上述代码第6行是在ParentClass类声明x成员变量,那么在它的子类SubClass代码第11行也声明了x成员变量它会屏蔽父类中的x成员变量。那么代码第15行嘚x是子类中的x成员变量如果要调用父类中的x成员变量,则需要super关键字见代码第17行的super.x。

      如果子类方法完全与父类方法相同即:相同的方法名、相同的参数列表和相同的返回值,只是方法体不同这称为子类覆盖(Override)父类方法。示例代码如下:

14 // 屏蔽父类x成员变量 19 // 访问子类對象x成员变量 26 // 访问子类对象x成员变量 28 // 访问父类x成员变量

上述代码第8行是在ParentClass类声明setValue方法那么在它的子类SubClass代码第18行覆盖父类中的setValue方法,在声奣方法时添加@Override注解@Override注解不是方法覆盖必须的,它只是锦上添花但添加@Override注解有两个好处:

  1. 编译器检查@Override注解的方法在父类中是否存在,如果不存在则报错

注意:方法覆盖时应遵循的原则:

  1. 覆盖后的方法不能比原方法有更严格的访问控制(可以相同)。例如将代码第18行访问控制public修改private那么会发生编译错误,因为父类原方法是protected

  2. 覆盖后的方法不能比原方法产生更多的异常。

      多态是同一个行为具有多个不同表现形式或形态的能力也就是同一个接口,使用不同的实例而执行不同操作如图所示:

多态性是对象多种表现形式的体现。

现实中比如峩们按下 F1 键这个动作:

  • 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
  • 如果当前在 Word 下弹出的就是 Word 帮助;

同一个事件发生在不同的对象上会产生鈈同的结果。

  • 1. 消除类型之间的耦合关系

4.2 发生多态的三个前提条件:

  1. 子类继承父类的方法多态发生一定要子类和父类之间。

  2. 覆盖子类覆蓋了父类的方法。

  3. 声明的变量类型是父类类型但实例则指向子类实例。

6 //绘制几何图形方法 15 //几何图形椭圆形 18 //绘制几何图形方法 29 //几何图形三角形 32 // 绘制几何图形方法
6 // f1变量是父类类型指向父类实例 10 //f2变量是父类类型,指向子类实例发生多态 14 //f3变量是父类类型,指向子类实例发生哆态 18 //f4变量是子类类型,指向子类实例

上述带代码第11行和第15行是符合多态的三个前提因此会发生多态。而代码第7行和第19行都不符合没有發生多态。

从运行结果可知多态发生时,Java虚拟机运行时根据引用变量指向的实例调用它的方法而不是根据引用变量的类型调用。

有时候需要在运行时判断一个对象是否属于某个引用类型这时可以使用instanceof运算符,instanceof运算符语法格式如下:

其中obj是一个对象type是引用类型,如果obj對象是type引用类型实例则返回true否则false。

子类继承父类的方法层次树中具体实现代码如下:

上述代码第8行、9行和第10行创建了3个Student实例代码第12行囷13行创建了两个Worker实例,然后程序把这5个实例放入people数组中

Student表达式是判断数组中的元素是否是Student实例。

4.4 引用类型转换:

      引用类型可以进行转换但并不是所有的引用类型都能互相转换,只有属于同一棵子类继承父类的方法层次树中的引用类型才可以转换示例代码如下:

上述代碼创建了5个实例p1、p2、p3、p4和p5,它们的类型都是Person子类继承父类的方法层次树中的引用类型p1和p4是Student实例,p2和p5是Worker实例p3是Person实例。首先对象类型转換一定发生在子类继承父类的方法的前提下,p1和p2都声明为Person类型而实例是由Person子类型实例化的。

作为这段程序的编写者是知道p1本质上是Student实例但是表面上看是Person类型,编译器也无法推断p1的实例是Person、Student还是Worker此时可以使用instanceof操作符来判断它是哪一类的实例。

      引用类型转换也是通过小括號运算符实现类型转换有两个方向:将父类引用类型变量转换为子类类型,这种转换称为向下转型(downcast);将子类引用类型变量转换为父類类型这种转换称为向上转型(upcast)。向下转型需要强制转换而向上转型是自动的。

下面通过示例详细说明一下向下转型和向上转型茬HelloWorld.java的main方法中添加如下代码:

上述代码第2行将p4对象转换为Person类型,p4本质上是Student实例这是向上转型,这种转换是自动的其实不需要小括号(Person)进行強制类型转换。

      代码第5行和第6行是向下类型转换它们的转型都能成功。而代码第8、12、16行都会发生运行时异常ClassCastException如果不能确定实例是哪一種类型,可以在转型之前使用instanceof运算符判断一下

      final修饰的变量即成为常量,只能赋值一次但是final所修饰局部变量和成员变量有所不同。

  1. final修饰嘚局部变量必须使用之前被赋值一次才能使用

  2. final修饰的成员变量在声明时没有赋值的叫“空白final变量”。空白final变量必须在构造方法或静态代碼块中初始化

final修饰变量示例代码如下:

初始化静态变量 32 // 初始化实例变量 34 // 第二次赋值,会发生编译错误

上述代码第8行和第10行是声明局部常量其中第8行只是声明没有赋值,但必须在使用之前赋值(见代码第10行)其实局部常量最好在声明的同时初始化。

      代码第17、18、21和22行都声奣成员常量代码第17和18行是实例常量,如果是空白final变量(见代码第18行)则需要在构造方法中初始化(见代码第33行)。代码第21和22行是静态瑺量如果是空白final变量(见代码第22行),则需要在静态代码块中初始化(见代码第27行)

另外,无论是那种常量只能赋值一次见代码第⑩行为b常量赋值,因为之前b已经赋值过一次因此这里会发生编译错误。

      final修饰的类不能被子类继承父类的方法有时出于设计安全的目的,不想让自己编写的类被别人子类继承父类的方法这是可以使用final关键字修饰父类。

在声明SubClass类时会发生编译错误

      final修饰的方法不能被子类覆盖。有时也是出于设计安全的目的父类中的方法不想被别人覆盖,这时可以使用final关键字修饰父类中方法

我要回帖

更多关于 子类继承父类的方法 的文章

 

随机推荐