java基础-继承

一个由其他类继承的类叫子类(也叫继承类,扩展类等),该类继承的类叫父类或超类。除了Object类意外,所有的类都有切仅有一个父类,如果一个类没有用extends关键词声明父类,则该类隐含继承Object类,因此如果一个类继承另外一个父类,而该父类可能又是继承的另外一个类,最终的起点在Object类。

java中继承的概念简单而强大,当你需要定义的一个类中的许多代码已经在另外一个类中存在时,我们就可以选择定义时继承该类,这样免去许多书写和调试的麻烦,子类能够继承父类的字段,方法和嵌套类,即类成员,构造器不是类成员,因此不会被继承,但是可以在子类中使用。

可继承成员的处理

子类继承父类中可视范围修饰词为public和protected的成员,无论子类和父类是否在同一个程序包中,如果同在一个程序包内,则子类还可以继承父类中仅包内可见(没有可视范围修饰词)的成员,针对于可继承的类成员,子类可进行如下处理:

  • 可直接用继承的字段,就像类中其他声明的字段一样。
  • 也可以在类中声明一个与继承字段名称相同的字段,即隐藏(不推荐这样做)。
  • 可以声明在父类中不存在的字段。
  • 可以直接使用继承的方法,就像类中其他声明的方法一样。
  • 也可以在类中声明一个与继承方法的签名相同的方法,即覆写。
  • 可以定义一个新的与继承方法签名相同的静态方法,即隐藏。
  • 也可以定义一个父类中不存在的方法。
  • 可以在类中定义可以使用隐含地或者使用关键词super调用父类中的构造器。

类型的转化

如下的赋值语句:

//1 编译可以通过
Object obj = new MountainBike();
//2 编译不能通过
MountainBike myBike = obj;
//3 转化操作,编译可以通过
MountainBike myBike = (MountainBike)obj;

上述代码中,MountainBike是由Object类多次继承下来的,所以将MountainBike类的实例赋值给类型为Object的变量不会出错,反过来,如果将Object对象赋值给类型为MountainBike的变量,就不能编译通过,此时我们使用一个转化操作,就可以将obj变量的类型转化成MountainBike类型,不过,如果变量obj实际指向的对象不是MountainBike类型的话,运行过程中就会抛出异常。

可以先通过instanceof操作符对一个变量指向的对象进行类型的判断,然后进行类型的转化:

if (obj instanceof MountainBike) {
    MountainBike myBike = (MountainBike)obj;
}

除了能够对与对象类型使用转化意外,基本数据类型也可以使用转化操作,如将字符型转化成整型的操作。

状态,实现和类型的多重继承

类和接口的重要区别是类能够声明字段,而接口不能(只能声明常量)声明字段,此外,类可以实例化而接口不能实例化。对象使用类中声明的字段存储其状态,java语言不允许继承多个类是为了防止继承多个类的状态造成的问题,假如一个类继承多个类,那么创建该类的实例时,那么如果该类继承的类中含有相同的方法或者字段,优先使用哪一个呢?由于接口不含有字段,因此不存在继承多个状态的问题。

实现的多重继承是指如果允许继承多个类,那么就会有多个类中的方法命名冲突的问题,然而类的声明是允许继承多个接口的,静态方法和默认方法会造成实现的多重继承问题,java编译器有一些规则来从多个相同签名的方法做出选择。

java允许多个类型的继承,即通过实现多个类,一个对象可以看做是有多个类型的,即其自身的类和类实现的接口。

覆写和隐藏方法

实例方法

子类中声明与父类中签名和返回类型相同的方法就会覆写父类中对应的方法,方法的覆写是子类和父类行为尽可能相近,而又允许做出相应调整,子类中如果包含与父类中签名相同的方法,则该方法返回类型必须与父类中相应的方法相同,或者是返回类型的子类型。

可以使用@Override注释覆写的方法,这样编译器便会检查是否成功覆写父类中的方法(有时候方法名称写错)。

静态方法

在子类中声明与父类中签名相同的方法会隐藏父类中对应的方法,方法的隐藏和方法的覆写差异在于:

  • 子类的对象调用覆写的方法是子类中声明的方法。
  • 而被隐藏的静态方法则取决与方法是被父类还是被子类调用,如果被父类调用,则执行父类中被隐藏的方法,被子类调用则执行子类中的方法。

接口中的方法

默认方法和抽象方法的继承就像实例方法一样,然而父类型的类或者接口含有相同签名默认方法时,java编译器的选择遵循如下两个原则:

  • 父类中的实例方法优先于接口中的默认方法被使用
  • 已经被覆写的方法会被忽略,这种通常在实现的两个接口继承同一个接口时发生,如下例所示:
public interface Animal {
    default public String identifyMyself() {
        return "I am an animal.";
    }
}

public interface EggLayer extends Animal {
    default public String identifyMyself() {
        return "I am able to lay eggs.";
    }
}

public interface FireBreather extends Animal { }

public class Dragon implements EggLayer, FireBreather {
    public static void main (String... args) {
        Dragon myApp = new Dragon();
        System.out.println(myApp.identifyMyself());
    }
}

上述代码输出:I am able to lay eggs

如果两个以上独立的默认方法发生冲突时,或者默认方法和抽象方法冲突时,java编译器会产生一个编译错误,你必须明确地覆写该方法,不过父类中的实例方法可以覆写实现接口的抽象方法。

注意:接口中的静态方法不会被继承。

可视范围修饰词

对于可视范围的控制,子类中对于继承的成员可视范围只能扩大而不能缩小,比如在一个接口中一个抽象方法的可视范围修饰词为protect,则实现该接口的类中对于该方法的声明的可视范围修饰词只能为protect或者public,否则将会编译出错。

多态

字典中对于多态的定义是指一个生物或者一个物种可以有不同的形态或者阶段,这一概念被应用到了面向对象的编程语言中,java也不例外。子类可以定义自己独特的行为也可以和父类由相同的功能,当然,这些功能都是通过类成员实现的。

java虚拟机(JVM)是根据实际引用的对象来调用方法的,而不是根据变量的类型,这一特性叫做虚拟方法调用(virtual method invocation),体现出了java语言的特征。

字段的隐藏

在一个类中声明和父类中名称相同的字段会隐藏父类中的相应的字段,而无论名称相同的字段是否是相同的类型,在子类中不能直接引用被隐藏的父类中的字段,而只能通过super关键词,一般不提倡隐藏字段,因为这样会使代码的易读性降低。

super关键词的使用

用来使用父类中的成员

当子类覆写父类中的方法时,你可以通过super关键词调用被覆写的方法实现,同时,super关键词也可以用于使用被隐藏的字段。

子类构造器中使用super()

在构造器中,使用super(var)可以调用父类中的构造器,圆括号内是构造器参数,在子类构造器中,父类构造器调用语句必须位于构造器主体中的第一行。

如果没有用super()明确调用父类中的构造器,则java编译器会自动给子类插入对于父类中不带参数构造器的调用,如果父类中不含有无参数构造器,则会编译出错,当然如果该类的超类是Object的话就不会有问题。

子类中的构造器一定会调用父类的构造器,父类的构造器也会调用自身继承的类的构造器,以此类推,最终每个类都会调用Object的构造器。

Final 方法和类

在方法的声明中加入修饰词final,那么该方法则不能被覆写,一般建议在构构造器中使用的方法定义为final方法。、

同样,在类的声明也可以加入修饰词final,那么该类就不能被继承,如String就不能被继承。

时间: 2024-10-26 16:32:45

java基础-继承的相关文章

古典音乐 (java基础 继承)

摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢! 一.前言 小朽不才,最近爱上了听古典音乐收录了,mozart ,贝多芬-等好听的歌很是喜欢.戴上耳机,打开电台,整理下java继承. 总结如下: 继承(extends) 方法覆盖(Mehtod Overriding) protected 向上转型 二. 继承(extends) 从编码中,咱们总是在不知不觉的用继承,明确的调用,或是隐式的调用了java根类Object.什

Java基础继承与多态

Java基础第九天 继承概述 引入 首先我来写两个代码: //定义学生类 class Student {     public void study(){ System.out.println("在教室学习"); } } //定义老师类 class Teacher { public void teach(){ System.out.println("在教室教书"); } } 我们观察上面两个代码: 发现name,age成员变量,以及getXxx()/setXxx()

黑马程序员----java基础----继承与多态,附相关面试题

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一:继承(掌握) (1)把多个类中相同的成员给提取出来定义到一个独立的类中.然后让这多个类和该独立的类产生一个关系, 这多个类就具备了这些内容.这个关系叫继承. (2)Java中如何表示继承呢?格式是什么呢? A:用关键字extends表示 B:格式: class 子类名 extends 父类名 {} (3)继承的好处: A:提高了代码的复用性 B:提高了代码的维护性 C:让类与类产生了一个关

java基础-继承:矩形体积类问题

28.按要求编写一个Java应用程序: (1)定义一个类,描述一个矩形,包含有长.宽两种属性,和计算面积方法. (2)编写一个类,继承自矩形类,同时该类描述长方体,具有长.宽.高属性, 和计算体积的方法. (3)编写一个测试类,对以上两个类进行测试,创建一个长方体,定义其长. 宽.高,输出其底面积和体积. package zhongqiuzuoye; //定义一个类,描述一个矩形,包含有长.宽两种属性,和计算面积方法. public class Juxing { private double x

java 基础-继承

1.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表.然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法showB输出大写的英文字母表.最后编写主类C,在主类的main方法中测试类A与类B. //父类 public class Zimubiao { void showA() { System.out.println("abcd"); } } //子类 public class Zimubiao2

黑马程序员--java基础------继承,抽象,接口

-----------android培训.java培训.java学习型技术博客.期待与您交流!------------  继承 一.概述         继承是面向对象的一个重要特征.当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可.这时,多个类可以称为子类,单独的这个类称为父类或者超类. 这样类与类之间就存在了继承的关系.子类可以直接访问父类中的非私有的属性和行为.在代码中通过extends关键字表示继承关系.例: class

java基础继承(重写)练习

. 1.实现如上类之间的继承关系,并编写Music类来测试这些类. //父类 public class Instrument { //输出弹奏乐器 public void play() { System.out.println("弹奏乐器"); } } public class Wind extends Instrument { //输出弹奏Wind public void play() { System.out.println("弹奏Wind"); } //调用“

Java基础---继承、抽象、接口

一.概述         继承是面向对象的一个重要特征.当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可.这时,多个类可以称为子类,单独的这个类称为父类或者超类.例如:猫和豹子都是猫科动物,那么就可以说描述猫这个对象创建的类,是子类:而描述猫科动物这个对象创建的类,就是父类. 这样类与类之间就存在了继承的关系.子类可以直接访问父类中的非私有的属性和行为.在代码中通过extends关键字表示继承关系.例: class Sonexte

java基础继承

为什么用继承: 因为继承可以减少代码的冗余,提高维护性,为了从根本上解决存在的问题,就需要继承,就是将多个类当中的相同的地方提取到一个父类当中.父类更通用,子类更具体. 1 父类的继承格式 2 语法:public class 父类{ 3 4 } public class 子类 extends 父类{ } 继承关键字:extends 在java中类的继承是单一继承,就是说一个子类只能拥有一个父类 super关键字  super的作用: 调用父类的构造方法 调用父类的方法 语法: 1. 子类不继承父