一,类加载机制
Java万物皆对象;
一个class文件对于Java来说,都是一个对象,而这个对象就是class对象。
1.class文件是什么?
class文件包含了该类的所有的信息(该类的成员属性,静态属性,构造方法,成员方法....)
2.class对象是什么?
class对象是class文件的访问入口
初识类加载过程
使用某个类时,如果该类的class文件没有加载到内存时,则系统会通过以下三个步骤来对该类进行初始化
1.类的加载(Load) → 2.类的连接(Link) → 3.类的初始化(Initialize)
-
类的加载(Load):将类的class文件读入内存,并为之创建一个java.lang.Class的对象,此过程由类加载器(ClassLoader )完成
-
类的连接(Link):将类中的数据加载到各个内存区域中
-
类的初始化(Initialize):JVM负责对类进行初始化
二,继承
1.理解:
子类继承父类所以的属性和方法
2.好处:
减少代码的冗余
3.缺点:
继承会增加类与类之间的关系,会增加代码维护难度
4.代码实现
//需求:编写中国人和日本人的类,创建各自的对象
//分析:
// 人类:属性:姓名,性别,年龄, 方法:吃饭,睡觉
// 中国人的类:属性:姓名,性别,年龄,身份证 方法:吃饭,睡觉,打太极
// 小日本的类:属性:姓名,性别,年龄,年号 方法:吃饭,睡觉,发地震
public class Test01{
public static void main(String[] args){
//创建对象
Chinese c = new Chinese();
//操作父类属性
c.name="周杰伦";
c.sex='男';
c.age = 20;
System.out.println(c.name);
System.out.println(c.sex);
System.out.println(c.age);
//操作子类属性
c.id ="1000233";
//调用父类方法
c.eat();
c.sleep();
//调用子类方法
c.playTauJi();
Japanese j = new Japanese();
j.name ="安倍晋三";
j.sex='男';
j.age=67;
//调用子类方法
j.earthquake();
}
}
public class Person{
String name;
char sex;
int age;
public void eat(){
System.out.println(this.name+"吃饭");
}
public void sleep(){
System.out.println(this.name+"睡觉");
}
}
public class Chinese extends Person{
String id;
public void playTaiJi(){
System.out.println("中国人打太极");
}
}
public class Japanese extends Person{
String yearNum;
public void earthquake(){
System.out.println("日本发地震");
}
}
三,继承的面试题
1.创建子类对象,会调用父类的构造方法吗?
会
代码解释:
public class Test01{
public static void main(String[] args){
Son s = new Son();
}
}
public class Father{
public Father(){
System.out.println("调用父类的构造方法");
}
}
public class Son extends Father{
public Son(){
System.out.println("调用子类的构造方法");
}
}
//会输出:调用父类的构造方法
// 调用子类的构造方法
2.创建子类对象为什么会调用父类的构造方法?
因为会在子类对象中开辟空间,用于存储父类的属性
3.创建子类对象,先调父类构造方法还是子类构造方法?
先调用子类的构造方法
代码解释:
public class Son extends Father{
public Son(){
//super(); //默认实现:调用父类的构造方法
System.out.println("调用子类的构造方法");
}
}
//理解:当添加子类的无参构造后,new了子类对象后直接调用子类的无参构造,然后再调用父类的无参构造,但是会先输出父类构造方法里的内容(即先完成父类的构造方法)
4.子类对象是否能继承父类所有的属性和方法?
在Java官网上,明确表示子类不能继承父类私有化属性和方法,这是站在使用的角度;实际上,子类能继承父类私有化的属性和方法,但是不能直接使用,可以在父类中编写公有方法去调用私有的属性和方法
四,super关键字
1.理解:
super表示父类;
2.作用:
1. super.属性 :在子类中,调用父类非私有化的成员属性
2. super.方法 :在子类中,调用父类非私有化的成员方法
3.super() : 在子类构造方法中的第一句调用父类的非私有化的构造方法
3.代码实现
//需求:编写中国人和日本人的类,创建各自的对象
//分析:
// 人类:属性:姓名,性别,年龄, 方法:吃饭,睡觉
// 中国人的类:属性:姓名,性别,年龄,身份证 方法:吃饭,睡觉,打太极
// 小日本的类:属性:姓名,性别,年龄,年号 方法:吃饭,睡觉,发地震
public class Test01{
public static void main(String[] args){
//创建对象
Chinese c = new Chinese("周杰伦",'男',20,"1302302");
//调用父类方法
c.eat();
c.sleep();
//调用子类方法
c.playTaiJi();
Japanese j = new Japanese("安倍晋三",'男',20,"昭和");
//调用子类方法
j.earthquake();
}
}
public class Person{
private String name;
private char sex;
private int age;
public Person(){
}
public Person(String name,char sex,int age){
this.name =name;
this.sex =sex;
this.age =age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(){
System.out.println(this.name+"吃饭");
}
public void sleep(){
System.out.println(this.name+"睡觉");
}
}
public class Chinese extends Person{
private String id;
public Chinese() {
}
public Chinese(String name, char sex, int age, String id) {
super(name, sex, age);
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void playTaiJi(){
System.out.println(super.getName()+"中国人打太极");//此处super可省略,调用了父类的共有的成员方法
}
}
public class Japanese extends Person{
private String yearNum;
public Japanese() {
}
public Japanese(String name, char sex, int age, String yearNum) {
super(name, sex, age);
this.yearNum = yearNum;
}
public String getYearNum() {
return yearNum;
}
public void setYearNum(String yearNum) {
this.yearNum = yearNum;
}
public void earthquake(){
System.out.println(super.getName()+"日本发地震");
}
}
小结:编写一个类的步骤:
1.属性 2.私有化属性 3.无参构造,有参构造 4.get/set方法 5.其他方法
五,重写
1.理解:
在子类中,将父类的方法重新写一遍
2.应用场景:
父类方法不能被改动时,并且父类方法不满足子类需求时,在子类中 重写一遍。
3.条件:
1.在子类中重写父类的方法;
2.返回值,方法名,参数列表必须根父类重写的方法一致
3.访问修饰符不能比父类更严格
@Override ----重写的注解; 注解:给程序员和系统解释代码信息
//接上面 "Chinese"类中的代码
@Override
public void eat(){
System.out.println(super.getName()+"山珍海味");
}
//此时主方法里面的 c.eat() 调用的就是子类重写后的方法