Java的继承
继承的本质是对某一批类的抽象。用extends关键字,子类(派生类)是父类(基类)的扩展。
-
Object类:Java中,无论写不写entents Object类,所有的类都默认直接或间接继承Object类。
-
super:可以和this关键字对比。this是本身调用者这个对象(无继承关系时也可以使用),super是指向父类对象的引用(只能在有继承关系时使用)。
-
方法重写(和重载不同意义):重写都是针对的方法,属性没有重写的说法。
继承
-
子类继承父类,会拥有父类的全部public属性和全部public方法。
-
子类继承父类,不会拥有父类的private属性和private方法。
-
Java的继承是单继承:一个儿子,只能有一个父亲;一个父类,可以用多个子类。
1、Person类(父类):
package com.WZ.Demo.ClassSet;
public class Person {
public int age = 5;
public int getAge(){
return this.age;
}
}
2、Student类(子类):
package com.WZ.Demo.ClassSet;
public class Student extends Person { }
3、main()方法:
package com.WZ.Demo.Application;
import com.WZ.Demo.ClassSet.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
System.out.println( student.getAge());
}
}
查看继承关系结构
鼠标点击在类名上,然后Ctrl + H。就可以看到该类的继承关系。
Super调用:属性和方法
this:调用的当前对象的
super:调用的父代对象的
1、父类:
package com.WZ.Demo.ClassSet;
public class Person {
public String name = "父代";
public void getName(){
System.out.println("输出的是:父代");;
}
}
2、子类:
package com.WZ.Demo.ClassSet;
public class Student extends Person {
public String name = "子代";
public void getName(){
System.out.println("输出的是:子代");;
}
public void test(String name)
{
System.out.println(name); //输出:Wang Zan,传进来的参数
System.out.println(this.name); //输出:子代,当前的属性值
System.out.println(super.name); //输出:父代,父代的属性值
this.getName(); //调用了当前的方法
super.getName(); //调用了父代的方法
}
}
3、main()方法
package com.WZ.Demo.Application;
import com.WZ.Demo.ClassSet.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("Wang Zan");
}
}
输出:
Wang Zan 子代 父代 输出的是:子代 输出的是:父代
Super调用:构造器
super:调用的是父代的构造器。
super和this不能同时调用构造方法,因为两个都要在第一行。
注意:
-
当父代的构造器是有参构造,没有显示的写无参构造,在子代不能调用父代的无参构造器。
-
创建子代对象:
2.1. 父代和子代都不写有参构造时:用无参构造创建对象,自动调用父代和子代的无参构造
2.2. 父代和子代都写有参构造时:用有参构造创建对象,自动调用父代的无参构造和子代的有参构造
1、父类:
package com.WZ.Demo.ClassSet;
public class Person {
public Person() {
System.out.println("调用了父代的无参构造器");
}
public Person(int a) {
System.out.println("调用了父代的有参构造器");
}
}
2、子类:
package com.WZ.Demo.ClassSet;
public class Student extends Person {
public Student() {
System.out.println("调用了子代的无参构造器");
}
public Student(int a) {
System.out.println("调用了子代的有参构造器");
}
}
3、main()方法
package com.WZ.Demo.Application;
import com.WZ.Demo.ClassSet.Student;
public class Application {
public static void main(String[] args) {
//用无参构造创建对象,自动调用父代和子代的无参构造
Student student1 = new Student();
System.out.println("===================");
//用有参构造创建对象,自动调用父代的无参构造和子代的有参构造
Student student2 = new Student(3);
}
}
输出:
调用了父代的无参构造器 调用了子代的无参构造器
=================== 调用了父代的无参构造器 调用了子代的有参构造器
上例中,输出调用了父代的无参构造器原因:
字类的构造器中,有个隐藏代码super(),它会自动调用父代的无参构造器。
且如果显示的写super()调用父类的构造器,必须写在子类构造器的第一行,否则报错。(super()可以不写,Java会默认调用)
下面两个子代写法等效:
写法1:显示写上super()
package com.WZ.Demo.ClassSet;
public class Student extends Person {
public Student() {
super();
System.out.println("调用了子代的无参构造器");
}
}
写法2:不写super()
package com.WZ.Demo.ClassSet;
public class Student extends Person {
public Student() {
System.out.println("调用了子代的无参构造器");
}
}
父类和子类关于有参构造和无参构造最重要的一句话:只要写了有参构造,无论无参构造有没有用,都显示写上
父类只写有参,不显示写无参:子类也无法用无参方法进行构造。
举例:

方法重写(和重载不是一个意思)
-
重写是方法的重写。针对的是父类功能子类不一定需要,或者不一定满足的时候,需要重写。
-
属性没有重写的概念
-
重写只与非静态方法有关(无static关键字)
-
重写的只能是public方法,private方法不能重写
- 重写需要有继承关系,是子类重写父类的方法。
5.2. 参数列表必须相同(否则就是重载了)
5.3. 修饰符,范围可以扩大,但不能缩小:public > protected > Default > private
5.4. 抛出异常:范围可以被缩小,但不能扩大:ClassNotFoundException ---> Exception(大)
static方法的调用,只和等号左侧有关,与右边new的数据无关。
解释下:
A a = new A();
B b = new A();
B是父代,A是子代,创建对象后,a调用的是a自己的static方法,b调用的是b自己的static方法。
所以输出:"B=>test()" 和"A=>test()"
1、父代
package com.WZ.Demo.ClassSet;
public class B {
public static void test_static() {
System.out.println("B=>test()");
}
}
2、子代
package com.WZ.Demo.ClassSet;
public class A extends B {
public static void test_static() {
System.out.println("A=>test()");
}
}
3、main()
com.WZ.Demo.Application;
import com.WZ.Demo.ClassSet.A;
import com.WZ.Demo.ClassSet.B;
public class Application {
public static void main(String[] args) {
A a = new A();
a.test_static(); //输出:A=>test()
//父类的引用指向了子类
B b = new A();
b.test_static(); //输出:B=>test()
输出:
A=>test() B=>test()
非static方法的子类和父类调用特点(上例中,父类和子类方法都去掉static)
首选,与static方法(静态方法)不同,非静态方法中,子类重写了父类方法,调用方法时,就调用自己的方法了。
简而言之:子类重写了父类的方法时,当用子类new了个对象,该对象调用的是子类的方法。
解释下:
A a = new A();
B b = new A();
B是父代,A是子代,创建对象后,a调用的是a自己的方法,b调用的也是a的方法。
所以输出:"A=>test()" 和"A=>test()"
完整代码如下:
1、父代
package com.WZ.Demo.ClassSet;
public class B {
public void test_static() {
System.out.println("B=>test()");
}
}
2、子代
package com.WZ.Demo.ClassSet;
public class A extends B {
public void test_static() {
System.out.println("A=>test()");
}
}
3、main()
package com.WZ.Demo.Application;
import com.WZ.Demo.ClassSet.A;
import com.WZ.Demo.ClassSet.B;
public class Application {
public static void main(String[] args) {
A a = new A();
a.test_static(); //输出:A=>test()
//父类的引用指向了子类
B b = new A();
b.test_static(); //输出:A=>test()
}
}
输出:
A=>test()
A=>test()
关于方法的重写(在子类中,采用Alt+Insert,可以Override Methods):
-
若在子类中,不重写父类方法,只是导入Override Methods,子类自动继承父类方法(super.test_static())。
package com.WZ.Demo.ClassSet;
public class A extends B {
-
若在子类中,重写父类方法,先删除子类自动继承父类方法(super.test_static()),然后重写。
package com.WZ.Demo.ClassSet;
public class A extends B {
第一种情况的完整代码如下:
1、父代
package com.WZ.Demo.ClassSet;
public class B {
public void test_static() {
System.out.println("B=>test()");
}
}
2、子代
package com.WZ.Demo.ClassSet;
public class A extends B {
3、main()
com.WZ.Demo.Application;
import com.WZ.Demo.ClassSet.A;
import com.WZ.Demo.ClassSet.B;
public class Application {
public static void main(String[] args) {
A a = new A();
a.test_static(); //输出:B=>test()
//父类的引用指向了子类
B b = new A();
b.test_static(); //输出:B=>test()
输出:
B=>test()
B=>test()
第二种情况的完整代码如下:
1、父代
package com.WZ.Demo.ClassSet;
public class B {
public void test_static() {
System.out.println("B=>test()");
}
}
2、子代
package com.WZ.Demo.ClassSet;
public class A extends B {
3、main()
package com.WZ.Demo.Application;
import com.WZ.Demo.ClassSet.A;
import com.WZ.Demo.ClassSet.B;
public class Application {
public static void main(String[] args) {
A a = new A();
a.test_static(); //输出:A=>test()
//父类的引用指向了子类
B b = new A();
b.test_static(); //输出:A=>test()
}
}
输出:
A=>test()
A=>test()


浙公网安备 33010602011771号