首页 > 编程语言 >Java 继承(扩展)

Java 继承(扩展)

时间:2023-02-09 17:12:55浏览次数:37  
标签:Java 继承 子类 扩展 访问 父类 方法 public

目录

1、简单介绍

什么是继承?extends 其实是扩展的意思

继承是类与类之间的一种关系,对某一批类中共有的方法和属性进行共性抽取,抽取出来的这个类也就是被继承的类称之为:父类 / 基类 / 超类;继承的类称之为:子类 / 派生类

为什么要使用继承?(或者说使用继承解决了什么问题?)

提高代码复用率

继承是多态的前提,没有继承即没有多态。

继承设计规范

子类们相同特征(共性属性、共性方法)放在父类中定义,子类独有的属性和行为应该定义在子类自己里面。

为什么这样做?

如果子类的独有属性、行为定义在父类中,会导致其他子类也会得到这些属性和行为,这不符合面向对象逻辑。

2、特点

  • java 语言是单继承的,不是多继承,但是可以多层继承。

    • 例如:A 继承 B,B 继承 C,C 再继承 D,……,X 继承 Object 类。
  • 一个子类的直接父类是唯一的,但是一个父类可以拥有很多个子类。

    • java 中所有的类都直接或间接继承自 Object(祖宗类)。
  • 在继承的关系中,“子类就是一个父类”。也就是说,子类可以被当作父类看待。

    • 关系:is-a。
    • 例如:父类是员工,子类是讲师,那么“讲师就是一个员工”。
  • 继承当中子类可以拥有父类的“内容”, 子类还可以拥有自己专有的内容。

  • 子类只能从被扩展的父类获得成员变量、方法和内部类(包括内部接口、枚举),不能获得构造器和初始化块。

3、语法格式

定义父类的格式和定义一个普通的类没有区别

  • 定义子类的格式:
public class 子类名称 extends 父类名称{
      // ...
}

4、成员的访问特点

子类和父类中成员变量重名的访问特点

在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问的规则是:

等号左边是谁,就优先用谁,没有则向上找。

子类和父类中成员方法重名的访问特点(对于非静态方法)

创建的对象是谁,就优先用谁,没有则向上找。

该方法属于谁时,先看子类中有没有,没有则向上找,不能去其他子类中找。

子类是否可以继承父类的私有成员变量?

  • 可以的,只是不能直接访问,可以在父类中设置相应的方法,在子类中进行访问。

子类是否可以继承父类的静态成员?

  • 有争议的知识点。
  • 子类可以直接使用父类的静态成员(共享)。
  • 但个人认为:子类不能继承父类的静态成员。(共享并非继承)。

对静态和非静态方法的测试:

// 父类
public class Fu {

	public static void print() {
		System.out.println("Fu==>print()");
	}

	public void show() {
		System.out.println("Fu==>show()");
	}
}
// 子类
public class Zi extends Fu {

	public static void print() {
		System.out.println("Zi==>print()");
	}

	public void show() {
		System.out.println("Zi==>show()");
	}
}
// 测试类
public class Demo01 {
	public static void main(String[] args) {
		Zi zi = new Zi();
		zi.print(); // 静态方法
		zi.show();  // 非静态方法

		Fu fu = new Zi();
		fu.print(); // 静态方法
		zi.show();  // 非静态方法
		  /*
       结果:
			Zi==>print()
			Zi==>show()
			Fu==>print()
			Zi==>show()
	   说明:
			静态方法是类的方法,非静态方法是对象的方法
			有 static 时,fu 调用了 Fu 类中的方法
			没有 static 时,fu 调用了 new 的对象 Zi 的方法
       */
	}
}

对实例变量的测试

如果子类定义了和父类同名的实例变量,则会发生子类实例变量隐藏父类实例变量的情况。

public class BaseClass {

   public  String name = "基类";
}
public class SubClass extends BaseClass {

   private  String name = "派生类";
}
public class Demo02 {
   public static void main(String[] args) {
      SubClass subClass = new SubClass();
      // 报错:因为派生类中 name 是 private 修饰的无法直接访问
      // System.out.println(subClass.name);
      // 向上强制类型转换 基类中 name 是 public 修饰的可以直接访问
      System.out.println(((BaseClass) subClass).name); // 基类

   }
}

同样

public class BaseClass {
   public  String name = "基类";
}
public class SubClass extends BaseClass {
   public  String name = "派生类";

}
public class Demo02 {
   public static void main(String[] args) {
      SubClass subClass = new SubClass();
      System.out.println(subClass.name); // 派生类
      System.out.println(((BaseClass) subClass).name); // 基类

   }
}

5、构造器的访问特点

子类继承父类后构造器的特点:

子类中所有的构造器默认都会先访问父类中无参的构造器,再执行自己的。

为什么?

1、子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使

用父类的数据。

2、子类初始化之前,一定要调用父类构造器先完成父类数据空间的初始化。

怎么调用父类构造器的?

子类构造器的第一行语句默认都是:super();,不写也存在。

继承后子类构造器如何访问父类有参构造器?

通过 super 关键字调用父类有参构造器的作用来初始化继承自父类的数据。

如果父类中没有无参构造器,只有有参构造器,会出现什么现象?

会报错,因为子类默认是调用父类无参构造器的。

如何解决?

子类构造器中可以通过书写 super(参数),手动调用父类的有参构造器。

注:

子类必须调用父类的构造方法,不写则赠送 super();,写了则用指定的。

在子类构造器中,super() / super(参数) 只能有一个,还必须是构造器语句中的第一句。

super() / super(参数) 不能出现在非构造器方法中

6、方法的覆盖重写

为什么要对基类中的方法进行重写?

因为基类中的方法不满足我们的需求,需要对其进行扩展,让派生类来满足我们需求。

注意:重写和重载是针对方法而言的,不针对属性

重写(override):子父类中,方法名称一样,参数列表也一样。

重载(overload):同一个类中,方法名称一样,参数列表不一样。

重写的条件:“两同两小一大”

  • “两同”:方法名称和形参列表要相同

  • “两小”:

    • 子类方法的返回值类型和父类方法的返回值类型相同,或者是父类返回值类型的子类;
    • 子类方法声明抛出的异常类和父类方法声明抛出的异常类相同,或者是父类抛出的异常类的子类;
  • “一大”:子类方法的访问权限和父类方法的访问权相同,或者更大;

覆盖重写注意事项:

  1. 不能重写被 final、static、private 修饰的方法
  2. 构造器不能被继承,更不能被覆盖
  3. 覆盖方法和被覆盖方法(这里指的是方法名称和参数列表要相同的)要么都是类方法,要么都是实例方法,不能一个是类方法,一个是实例方法。

父类的私有成员方法对子类是隐藏的,无法直接在子类中访问,更不能重写。如果子类中定义了一个与父类 private 方法相同方法名称、参数列表、返回值类型的方法,也无法构成重写,只是在子类中重写定义了一个新方法。

代码示例:

public class BaseClass {

	// test()方法是private修饰的,子类不可访问该方法
	private  void test() {
	}
}
public class SubClass extends BaseClass {

	// 此处并不是方法重写,所以可以增加static关键字
	public static void test() {
	}
}

7、this 和 super 关键字

this:代表本类对象的引用

  1. 在本类的成员方法中,访问本类的成员变量。
  2. 在本类的成员方法中,访问本类的另一个成员方法。
  3. 在本类的构造方法中,访问本类的另一个构造方法。

super:代表父类对象存储空间的标识

  1. 在子类的成员方法中,访问父类的成员变量。
  2. 在子类的成员方法中,访问父类的成员方法。
  3. 在子类的构造方法中,访问父类的构造方法。

注:

  • this(参数) 调用也必须是构造方法的第一个语句,唯一一个。
  • super 和 this 两种构造调用,不能同时使用。
  • this 和 super 都不能出现在 static 修饰的类方法中。

标签:Java,继承,子类,扩展,访问,父类,方法,public
From: https://www.cnblogs.com/sunzhongjie/p/17106263.html

相关文章

  • Java基础知识
    Java基础注释单行注释//单行注释多行注释/*多行注释多行注释*/文档注释/***文档注释*/标识符只能以字母、$、_开头首字符之后可以是字母、$、_、数字的组......
  • Java基础知识点(键盘录入、算术运算符、类型转换)
    一:键盘录入Java帮我们写好一个类叫Scanner,这个类这个类就可以接收键盘输入的内容步骤一:导包——Scanner这个类在哪(导包必须出现在类定义的上面)importjava.util.Scanner;步......
  • java基础知识精华总结 java面试题
    1、文件拷贝,把一个文件的内容拷贝到另外一个文件里packageorder;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;import......
  • json转java以及校验用户名是否存在
    json转java步骤:1.导入jackson相关jar包2.创建Jackson核心对象ObjectMapper3.调用ObjectMapper的相关方法进行转换1.readValue(json字符串数据,C......
  • Java Swing 禁止黏贴动作
    碰到一个需求,不让复制黏贴。可考的方法有:1重写JTextFieldpaste函数  2 删除组件ActionMap中与CTRL+V按键相关的操作因为JTextField已经被封装了一层,就不想再......
  • 用c编译 php/python拓展(swig生成PHP扩展)
    https://blog.csdn.net/cuxiong8996/article/details/107153840 swig生成了PHP的扩展:https://blog.csdn.net/weixin_39622419/article/details/1160659781、安装swig......
  • 使用AES的256位密钥加解密报错java.security.InvalidKeyException: Illegal key size
     使用AES的256位密钥加解密报错java.security.InvalidKeyException:Illegalkeysize。编写微信小程序在获取用户时,需要根据小程序传来的iv,encryptedData,和se......
  • JAVA缓存规范 —— 虽迟但到的JCache API与天生不俗的Spring Cache
    大家好,又见面了。本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面。如果感兴趣,欢迎关注以获取后续更新。有......
  • java冒泡排序
    java/**冒泡排序1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置2.每一次比较,都会产生一个最大或者最小的数字;3.下一轮则可以少一次排序!4......
  • java基础
    注释注释并不会被执行,是给我们写代码的人看的;书写注释是一个非常好的习惯单行注释//多行注释/*注释*/文档注释/**文档*/标识符关键字java所有的组成部......