变量继承的一些讲解
前言
Github:https://github.com/HealerJean
1、Supper
1.1、父类
public class Father {
public Father(){
System.out.println("Father constructor");
}
public Father(String str){
System.out.println("Father Param constructor "+ str);
}
public void otheMethod(){
System.out.println("Father Method");
}
}
1.2、子类
public class Son extends Father {
/**
* 一、无参构造器
* 1、写不写 super(); 都会调用父类中的无参构造器
*/
public Son(){
super();
System.out.println( "Son constructor");
System.out.println("---------------------");
//死循环 还会调用父类
Son son = new Son();
}
/**
* 二、有参构造器
1、下面 写super() 和 super(str) 会调用父类中对应的构造器
2、不写 suppr时候,像无参构造器那样自动执行 父类中supper()
*/
public Son(String str){
// 1、什么都不写会主动调用父类中的 supper()
// 2、super(str); 会调用父类中的有参构造器 ,不会调用无参构造器
super(str);
System.out.println( "Son param constructor");
System.out.println("---------------------");
}
/**
* 三、不是构造器的方法
1、 super() 等 相同类型 只能用在构造器中
2、super.父类方法 可以放在任意方法的任意位置
*/
@Override
public void otheMethod(){
//super.otheMethod();
System.out.println("Son Test Son");
//super.otheMethod();
System.out.println("---------------------");
}
}
执行测试
public class D02_SuperMain {
@Test
public void testSupperFatherConstrustor() {
Son son = new Son();
Father father = new Son();
}
@Test
public void testSupperFatherParamConstrustor() throws Exception {
String str = "HealerJean";
Father fatherParam = new Son(str);
}
@Test
public void testOtherMethod() {
Father fatherParam = new Son();
fatherParam.otheMethod();
}
}
2、static
2.1、对于静态字段,只有直接定义这个类的字段的类才会被加载
解释:很明显没有输出子类SubClass中的static代码块的信息,对于静态字段,只有直接定义这个类的字段的类才会被加载。
//1、父类
public class SuperClass {
static{
System.out.println("super class init!");
}
public static int a = 1;
public final static int b = 1;
}
//2、子类
public class SubClass extends SuperClass{
static{
System.out.println("SubClass init!");
}
}
//3、测试
public class Test {
static{
System.out.println("test class init!");
}
public static void main(String[] args){
System.out.println(SubClass.a);
}
}
test class init!
super class init!
1
2.2、当初始化类的时候,如果他的父类还没有被初始化,则需要先初始化它的父类
//1、父类
public class SuperClass {
static{
System.out.println("super class init!");
}
public static int a = 1;
public final static int b = 1;
}
//子类
public class SubClass extends SuperClass{
static{
System.out.println("SubClass init!");
}
public static int s = 2; //对于静态字段,只有指定定义这个字段的类才会初始化
}
public class Test {
static{
System.out.println("test class init!");
}
public static void main(String[] args){
System.out.println(SubClass.s);
}
}
控制台
test class init!
super class init!
SubClass init!
2
2.3、讲static变成final
public final static int s = 2; //
变成final常亮的时则不会初始化任何,因为它放到了常亮池中,并不是在类中获取的,所以不需要初始化,控制台只会打印出2
//1、父类
public class SuperClass {
static{
System.out.println("super class init!");
}
public static int a = 1;
public final static int b = 1;
}
//子类
public class SubClass extends SuperClass{
static{
System.out.println("SubClass init!");
}
public final static int s = 2;
}
public class Test {
static{
System.out.println("test class init!");
}
public static void main(String[] args){
System.out.println(SubClass.s);
}
}
控制台
test class init!
2
3、子类变量不和父类变量重复
- 子类继承自父类的变量,其实是相当于复制了一个副本,不会改变父类自身变量的值
3.1、父类
@Data
public class Father {
public String name = "父亲";
public String printName() {
return this.name;
}
public String printGetName() {
return this.getName();
}
}
3.2、子类
@Data
public class Son extends Father{
@Override
public String printName() {
return this.name;
}
@Override
public String printGetName() {
return this.getName();
}
}
执行测试
/**
* 子类继承自父类的变量,其实是相当于复制了一个副本
*/
@Test
public void test1(){
Father father = new Son();
log.info("father.name:【{}】", father.name);
// 父亲
log.info("father.printName:【{}】", father.printName());
// 父亲
log.info("father.printGetName:【{}】", father.printGetName());
// 父亲
log.info("--------");
father.name = "father = name";
log.info("father.name:【{}】", father.name);
// 【father = name】
log.info(" ((Son) father).name:【{}】", ((Son) father).name);
// 【father = name】
log.info("father.getName:【{}】", father.getName());
// 【father = name】
log.info("father.printName:【{}】", father.printName());
// 【father = name】
log.info("father.printGetName:【{}】", father.printGetName());
// 【father = name】
log.info("--------");
//子类中虽然有方法,但是没有变量,所以方法调用的还是父类的
father.setName("father set name");
log.info("father.name:【{}】", father.name);
// 【father set name】
log.info("father.name:【{}】", ((Son) father).name);
// 【father set name】
log.info("father.getName:【{}】", father.getName());
// 【father set name】
log.info("father.printName:【{}】", father.printName());
// 【father set name】
log.info("father.printGetName:【{}】", father.printGetName());
// 【father set name】
log.info("--------");
Son son = new Son();
son.name = "son == name" ;
//子类强制转化为父类
father = son;
log.info("father.name:【{}】", father.name);
// 【父亲】
log.info("father.name:【{}】", ((Son) father).name);
// 【son == name】
log.info("father.getName:【{}】", father.getName());
// 【son == name】
log.info("father.printName:【{}】", father.printName());
// 【son == name】
log.info("father.printGetName:【{}】", father.printGetName());
// 【son == name】
log.info("--------");
}
4、子类变量和父类变量名字相同
-
子类中声明了和父类名称一样的变量,则子类中对自己声明的变量的修改,不影响父类中变量的值
-
变量赋值
-
**变量直接赋值(=)(son.name father.name),改变的自己的变量值或者是父类的变量值, **
-
如果setName,肯定是看被实例化的对象是谁,那就给自己赋值啊,因为调用的方法肯定是自己内部的。
-
4.1、父类
@Data
public class Father {
public String name = "父亲";
public String printName() {
return this.name;
}
public String printGetName() {
return this.getName();
}
}
4.2、子类
@Data
public class Son extends Father{
public String name = "儿子";
@Override
public String printName() {
return this.name;
}
@Override
public String printGetName() {
return this.getName();
}
}
执行测试
/**
* 1、子类中声明了和父类名称一样的变量,则子类中对自己声明的变量的修改,不影响父类中改变量的值
* 2、 变量直接赋值(=)(son.name father.name),改变的自己的变量值或者是父类的变量值,
* 如果setName,肯定是看被实例化的对象是谁,那就给自己赋值啊,因为调用的方法肯定是自己内部的。
*/
@Test
public void test2() {
Father father = new Son();
log.info("father.name:【{}】", father.name);
// 【父亲】 (这个变量是父类的)
log.info("father.printName:【{}】", father.printName());
// 【儿子】 (方法是子类的)
log.info("father.printGetName:【{}】", father.printGetName());
// 【儿子】 (方法是子类的)
log.info("--------");
//1、父类中有变量名,所以改变的是父类中的变量
father.name = "father = name";
log.info("father.name:【{}】", father.name);
// 【father = name】 //父类中的属性
log.info(" ((Son) father).name:【{}】", ((Son) father).name);
// 【儿子】 (强制转化成了子类,因为子类中有该属性,所以打印的是子类的变量的值)
log.info("father.getName:【{}】", father.getName());
// 【儿子】(方法是子类的)
log.info("father.printName:【{}】", father.printName());
// 【儿子】(方法是子类的)
log.info("father.printGetName:【{}】", father.printGetName());
// 【儿子】(方法是子类的)
log.info("--------");
//2、子类中有方法且有变量,所以 调用的是子类的方法,子类的name值改变了,父类没有改变
father.setName("father set name");
log.info("father.name:【{}】", father.name);
// 【father = name】 子类中声明了和父类名称一样的变量,则子类中对自己声明的变量的修改,不影响父类中变量的值
log.info("father.name:【{}】", ((Son) father).name);
// 【father set name】 (强制转化成了子类,因为子类中有该属性,所以打印的是子类的变量的值)
log.info("father.getName:【{}】", father.getName());
// 【father set name】
log.info("father.printName:【{}】", father.printName());
// 【father set name】
log.info("father.printGetName:【{}】", father.printGetName());
// 【father set name】
log.info("--------");
}