13.继承
1.继承
关键字:extends
class Father{ public int num1=10; private int num2=20; protected int num3=30; public Father(int num1,int num2,int num3){ this.num1=num1; this.num2=num2; this.num3=num3; } public Father(){ System.out.println("Father"); } @Override public String toString() { return String.format("%d %d %d",num1,num2,num3); } } class Son extends Father{ public Son(int num1,int num2,int num3){ super(num1,num2,num3); } @Override public String toString() { return super.toString(); }
public static void main(String[] args){
System.out.println(new Son(1,2,3));
} }//输出 1 2 3
重点
a.创建子类对象的时候会调用父类的构造函数,如果是无参数的构造函数,会自动的调用,不用写super()
b.Father father=new Son();//Son的实例但是进行了向上转型,father引用可以调用Father类中的函数,以及子类中被重写的函数(多态),但是父类的引用是不能调用子类的属性的,因为多态只针对方法不针对属性
例子:
public class Main { public static void main(String[] args){ /*创建子类对象的时候会调用子类的构造函数*/ Son son=new Son(); /*输出num1的值*/ Father father=new Son(); System.out.println(father.num1); /*调用函数f()*/ father.f(); } } class Father{ public int num1=10; public Father(){ System.out.println("Constructor of Father"); } public void f(){ System.out.println("Father's f()"); } } class Son extends Father{ public int num1=20; public Son(){ System.out.println("Constructor of Son"); } @Override public void f(){ System.out.println("Son's f()"); } }//输出:
Constructor of Father
Constructor of Son
Constructor of Father
Constructor of Son
10
Son's f()
覆盖与重载
- 注意:重载与覆盖的区别
- 重载(函数名称一样、参数的类型或者个不一致、与返回值无关)
- 覆盖(必须是有继承关系的两个类之间,函数的访问权限,函数名称,参数的类型个数都必须一致)
- @Override之后必须是覆盖而不能是重载--经常用在实现接口的函数的时候
Public、private、protected关键字
class A{ public String name=new String(“Tom”); protected String school=new String(“SouthEast University”); private String sex=new String(“M”); }
- public关键字不做过多的解释,通过指向A对象的引用,可以访问name属性
- private关键字,在A的类作用域之外,不能直接使用sex熟悉
- protected关键字
-
- 1.同包内protected与public相同
- 2.不同包内,2.1不是A的子类与private相同,
-
- 2.2是A的子类与public相同(只能在子类的作用域内),这就是为什么下边的代码为什么不能执行的原因
public class Test{ public static void main(String[] args){ Object obj=new Object(); System.out.println(obj.hashCode()); } }
//解释
按道理所有的类都是Object的子类,hahCode是protected函数,也就是说对于Object的子类,都可以执行hashCode()函数,但是必须在子类包中,这里就是Object所在的包中
这样写就是没问题的
@Override
public int hashCode(){
return super.hashCode();
}
- 2.2是A的子类与public相同(只能在子类的作用域内),这就是为什么下边的代码为什么不能执行的原因
-
-
- 省去包修饰符是包访问权限
关键字:final
作用如下
- 修饰属性,表示编译器常量
-
- final int a=9;//被初始化之后就不能改变--一般常量
- static final int A=9;//静态常量--类的常量
- 备注:Java中的final变量在定义的时候可以不进行初始化,但是初始化之后就不能修改常量的值
-
- eg:
- final int m;
- m=30;
- m=20;//Wrong
-
-
- 修饰对象和数组引用,表示引用不能改变“指向”
-
- final int[] a=new int[]{1,2,3};
- a[0]=1000;//可以改变数组的值
- a=new int [20];//Wrong 不能改变a的引用
-
- 修饰方法,表示函数不能被重写(覆盖)
- private 其实就是隐式的final函数,但是本质还是不一样的,只能说peivate 函数是有final关键字的
-
- 1.final 函数,子类中不能添加同名同参数的函数
- 2.private函数,子类中可以添加同名同参数的函数,但是这个不是重写,只是添加了自己的同名函数,与父类无关--------强烈建议避免这样写
-
class Instrument { private void display(){System.out.println("Instrument's display");}//无法被覆盖 } public class Wind extends Instrument{ private void display(){System.out.println("Wind's display");}//并不是覆盖父类的函数,而是添加自己的函数 public static void main(String[] args){ Instrument instrument=new Wind();//向上转型为父类的对象同时丢失父类的private方法 instrument.display();//Wrong } }
-
- 修饰类,表示类不能被继承