什么是基类
基类就是父类
,Object类是所有类的父类,子类继承父类,继承并重写父类的方法和非私有成员变量。
比如我下面定义一个基类,如下图:
package;
import java.io.Serializable;
import java.sql.Timestamp;
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/** 创建者 */
private String createBy;
/** 创建时间 */
private Timestamp createTime;
/** 更新者 */
private String updateBy;
/** 更新时间 */
private Timestamp updateTime;
/** 备注 */
private String remark;
}
什么是派生类
派生类
是在继承父类
及基础上增添了新的东西
,派生是依存于继承的,子类在拿来父类的东西去使用的同时,可以增添新的东西或者对继承来的东西进行覆写让其适用于子类。
父类的派生类,如下图:
package;
public class Book extends BaseEntity {
/** 书籍名称 */
private static String bookName;
}
基类和派生类的使用
使用如下:
package;
public class People {
public People() {
System.out.println("我是人");
}
}
package;
public class Student extends People {
public Student() {
System.out.println("我是学生");
}
}
class Test {
public static void main(String[] args) {
new Student();
}
}
输出结果:
我是人
我是学生
可以发现基类的构造器先被初始化
。
但是当构造器有参数时,那就必须使用关键字super现实地编写调用基类构造器的代码。
package;
public class People {
private static String name;
public People(String name) {
System.out.println("我是" + name + "的人");
}
}
package;
public class Student extends People {
private static String name;
public Student(String name) {
super(name);
System.out.println("我是叫" + name + "的学生");
}
}
class Test {
public static void main(String[] args) {
new Student("张三");
}
}
输出结果:
我是张三的人
我是叫张三的学生
如果注释掉上面的super(name);将会报错。原因是派生类必须调用基类构造器。因为实例化派生类时,基类也会被实例化,如果不调用基类的构造器,基类将不会被实例化,所以派生类没有调用基类构造器会报错。
如果给基类加无参构造方法就不会报错,代码如下:
package;
public class People {
private static String name;
public People() {
System.out.println("我是人");
}
public People(String name) {
System.out.println("我是" + name + "的人");
}
}
package;
public class Student extends People {
private static String name;
public Student(String name) {
System.out.println("我是叫" + name + "的学生");
}
}
class Test {
public static void main(String[] args) {
new Student("张三");
}
}
输出结果:
我是人
我是叫张三的学生
所以在们写代码的时候要养成好习惯给类加上无参构造方法,增加程序的健壮性。
派生类继承了基类的所有public和protected属性和方法,代码如下:
package;
public class People {
public String name;
protected Integer age;
private String sex;
public People() {
}
public People(String name, Integer age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getSex() {
return sex;
}
}
输出结果:
name = 张三
age = 16
这里无法使用student.sex,编译报错,因为基类的sex属性被private私有化了
,只能通过student.getSex()
获取。
如果派生类定义了和基类一样的属性或方法,将覆盖基类的属性和方法
,代码如下:
package;
public class Student extends People {
public String name;
protected Integer age;
private String sex;
public Student(String name, Integer age, String sex) {
super(name, age, sex);
}
}
class Test {
public static void main(String[] args) {
Student student = new Student("张三", 16, "男");
String name = student.name;
Integer age = student.age;
//String sex = student.sex;
System.out.println("name = " + name);
System.out.println("age = " + age);
//System.out.println("sex = " + sex);
}
}
输出结果:
name = null
age = null
只有当派生类的属性也被实例化时,才会得到属性的值,代码如下:
package;
public class Student extends People {
public String name;
protected Integer age;
private String sex;
public Student(String name, Integer age, String sex) {
super(name, age, sex);
this.name = name;
this.age = age;
this.sex = sex;
}
}
class Test {
public static void main(String[] args) {
Student student = new Student("张三", 16, "男");
String name = student.name;
Integer age = student.age;
//String sex = student.getSex();
System.out.println("name = " + name);
System.out.println("age = " + age);
//System.out.println("sex = " + sex);
}
}
输出结果:
name = 张三
age = 16
要注意的是,super必须在构造器的最前面
,不然会报错。
如下图: