继承、super、final
类的继承
calsss 子类名 extends 父类名{
方法、属性;
}
继承,青出于蓝——子类中可以定义新的方法、属性
package test1;
//定义父类
class Parent{
String name;
double property;
public void say(){
System.out.println(name+"的财产:"+ property);
}
}
//子类继承父类
class Child extends Parent{
int age;
public void sayAge(){
System.out.println(name+"的年龄:"+age);
}
}
public class Class1{
public static void main(String[] args){
//初始化对象、属性
Child c = new Child();
c.name = "小明";
c.property = 1000;
c.age = 20;
//调用方法
c.say();
c.sayAge();
}
}
小明的财产:1000.0
小明的年龄:20
多重?多层!
就像人类,只能有一个亲爹一样。
错误的
class A{}
class B{}
class C extends A,B{}
可以多层次继承
class A{}
class B extends A{}
class C extends B{}
重写方法
在子类中对say()进行重新编写
package test1;
//父类:打印: 父辈
class Parent{
protected void say(){
System.out.println("父辈");
}
}
//子类对父类继承并重写——打印: 父辈
class Child extends Parent{
public void say(){
System.out.println("子女");
}
}
public class Class1{
public static void main(String[] args){
Child c = new Child();
c.say();
}
}
重载与重写的区别:
重载:在一个类中
重写:在子类与父类之间
重载:方法名相同,参数个数和参数类型不同
重写:子类和父类的方法名、参数列表、返回值相同(此处是void)。
super
如上,say()已经被重新改写,如果还要访问,就使用super()
super.say();
package test1;
//父类:打印: 父辈
class Parent{
String name ="Parent";
public void say(){
System.out.println("父辈");
}
}
//子类对父类继承并重写——打印: 父辈
class Child extends Parent{
public void say(){
String name = super.name; //name赋值为父辈
System.out.println("姓名:"+name);
super.say(); //调用父类的say()
}
}
public class Class1{
public static void main(String[] args){
//初始化并调用 孩子说——继承时带上了super,调用时直接化身父辈了
Child c = new Child();
c.say();
}
}
姓名:Parent
父辈
super调用父类的构造方法
在继承中,实例化子类对象的时候,会首先调用父类的构造方法,再调用子类的构造方法。
子类继承父类的时候,并没有继承父类的构造方法,但是子类的构造方法可以调用父类的构造方法。
在一个构造方法中调用另一个重载的构造方法的时候应该使用this,再子类构造方法中调用父类的构造方法时应该使用super
并且:super关键字调用构造方法和this调用构造方法类似,该语句必须位于子类构造方法的第一行,否则编译出错。
super([参数列表])
package test1;
class Parent{
String name ;
//父类的构造方法
public Parent(String name){
this.name = name;
}
public void say(){
System.out.println("父辈");
}
}
class Child extends Parent{
//子类的构造方法
public Child(){
//用super变成父类的
super("Parent");
}
public void say(){
System.out.println("姓名:"+name);
}
}
public class Class1{
public static void main(String[] args){
//初始化并调用 孩子说
Child c = new Child();
c.say();
}}
姓名:Parent
从结果看来,实例化Child类对象时调用了父类的有参构造方法。
子类中如果没有显式地调用父类的构造方法,就会自动调用父类中不带参数的构造方法,如下例
这里报错,
是因为Child类的构造方法中没有显式调用父类构造方法,便会默认调用父类无参构造方法,
而父类中显式定义了有参的构造方法,此时编译器不再自动生成默认的构造方法。
因此,程序找不到无参构造方法而报错。
package test1;
//定义父类
class Parent{
String name;
//定义父类有参构造方法
public Parent(String name){
this.name = name;
System.out.println("Parent(String name)");
}
}
//子类继承
class Child extends Parent{
//定义子类无参构造方法
public Child(){
System.out.println("Child()");
}
public void say(){
System.out.println("姓名:" + name);
}
}
public class Class1{
public static void main(String[] args){
Child c = new Child();
}
}
Implicit super constructor Parent() is undefined.
未定义隐式构造方法
解决方法显而易见:在子类显式调用父类中定义的构造方法,也可以在父类中显式定义无参构造方法。
package test1;
class Parent{
String name;
//定义无参构造方法
public Parent(){
System.out.println("Parent()");
}
//定义有参构造方法
public Parent(String name){
this.name = name;
System.out.println("Parent(String name)");
}
}
class Child extends Parent{
//定义无参构造方法
public Child(){
System.out.println("Child()");
}
public void say(){
System.out.println("姓名:" + name);
}
}
public class Class1{
public static void main(String[] args){
Child c = new Child();
}
}
Parent()
Child()
Final
final 关键字的作用下:
class 不能被继承
final 不能被重写
变量--成为常量,不能再修改
总之,final就是最终了,就是什么都不能再改变了。
当final只声明未初始化会报错
final修饰了成员变量PI的时候,并未初始化,这时候会报错,然后我们再在Parent的构造方法里给PI初始化
package test1;
class Parent{
//final!!
public Parent(){
PI = 3.14;
}
final double PI;
public void say(){
System.out.println(this.PI);
}
}
class Child extends Parent{
}
public class Class1{
public static void main(String[] args){
Child c = new Child();
c.say();
}
}
3.14
---------------------------
“朝着一个既定的方向去努力,就算没有天赋,在时间的积累下应该也能稍稍有点成就吧。”