first:super与this
public class Person{
protected String name="tao";
}
public class Student extends Person{
private Stirng name="fetters";
public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
public class Application{
public static void main(String[] args){
Student student=new student();
student.test("桃");
}
}
//输出结果
桃
fetters
tao
public class Person{
protected String name="tao";
public void print(){
System.out.print("Person");
}
}
public class Student extends Person{
private Stirng name="fetters";
public void print(){
System.out.print("Student");
}
public void test(){
print();
this.print();
super.print();
}
}
public class Application{
public static void main(String[] args){
Student student=new student();
student.test();
}
}
//输出结果
Student
Student
Person
public class Person{
protected String name="tao";
public Person(){
System.out.print("Person无参执行了");
}
public void print(){
System.out.print("Person");
}
}
public class Student extends Person{
private Stirng name="fetters";
public Student(){
//隐藏代码:默认调用了父类的无参构造
super();//调用父类的构造器,必须在子类的构造器中的第一行
System.out.print("Student无参执行了");
}
public void print(){
System.out.print("Student");
}
}
public class Application{
public static void main(String[] args){
Student student=new student();
}
}
//输出结果
Person无参执行了
Student无参执行了
Note
super注意点
- [ ] super调用父类的方法,必须在构造方法的第一个
- [ ] super必须只能出现在子类的方法或者构造方法中!
- [ ] super与this不能同时调用构造方法
Vs this:
- 代表的对象不同:super:代表父类对象的应用 this:本身调用者这个对象
- 前提:this:没有继承也可以使用 super:只有在继承条件下才可以使用
- 构造方法:this();本类的构造 super();父类的构造
1.继承
继承的主要作用在于,在已有基础上继续进行功能的扩充。
若没有继承:
class Person {
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
}
class Student {
private String name;
private int age;
private String schoolName;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
public String getSchoolName()
{
return schoolName;
}
public void setSchoolName(String schoolName)
{
this.schoolName=schoolName;
}
}
以上是我们定义类的方式,含有大量重复的代码,java语言一般不允许大量重复的代码出现,这段代码不仅从代码上重复,而且从概念上讲学生一定是人,只是学生类描述的范围小,具备更多的属性和方法,这个时候想要消除结构定义上的重复,就要用到继承。
1.1 继承的实现
在Java中,继承用extends关键字来实现,语法:class 子类 extends 父类{}
(注意:``打出来)
所以可将上述代码改为:
class Person {
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
}
class Student extends Person{
}
public class Test2{
public static void main(String[] args)
{
Student student=new Student();
student.setName("花花");
student.setAge(18);
System.out.println("姓名:"+student.getName()+" 年龄:"+student.getAge());
}
}
通过以上代码可以发现,当发生了类继承关系之后,子类可以直接继承父类的操作,可以实现代码的重用,子类最低也维持和父类相同的功能。
子类也可以进行功能上的扩充。
class Person {
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
}
class Student extends Person{
private String schoolName;
public String getSchoolName()
{
return schoolName;
}
public void setSchoolName(String schoolName)
{
this.schoolName=schoolName;
}
}
public class Test2{
public static void main(String[] args)
{
Student student=new Student();
student.setName("花花");
student.setAge(18);
student.setSchoolName("励志中学");
System.out.println("学校:"+student.getSchoolName() +" 姓名:"+student.getName()+" 年龄:"+student.getAge());
}
}
继承的主要作用是对类进行扩充以及代码的重用!
1.2 继承的限制
1.2.1 子类对象在进行实例化前首先调用父类构造方法,再调用子类构造方法实例化子类对象。
class Person {
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
//构造方法
public Person()
{
System.out.println("父类的构造方法");
}
}
class Student extends Person{
private String schoolName;
public String getSchoolName()
{
return schoolName;
}
public void setSchoolName(String schoolName)
{
this.schoolName=schoolName;
}
//构造方法
public Student()
{
//隐藏代码:默认调用了父类的无参构造
super();//调用父类的构造器,必须在子类的构造器中的第一行
System.out.println("子类的构造方法");
}
}
public class Test2{
public static void main(String[] args)
{
Student student=new Student();
student.setName("花花");
student.setAge(18);
student.setSchoolName("励志中学");
System.out.println("学校:"+student.getSchoolName() +" 姓名:"+student.getName()+" 年龄:"+student.getAge());
}
}
实际在子类构造方法中,相当于隐含了一个语句super(),调用父类的无参构造。同时如果父类里没有提供无参构造,那么这个时候就必须使用super(参数)明确指明要调用的父类构造方法。
1.2.2 Java只允许单继承不允许多继承(一个子类继承一个父类)
eg:错误的继承:
class A{
}
class B{
}
class C extends A,B{
}
C继承A和B的主要目的是拥有A和B中的操作,为了实现这样的目的,可以采用多层继承的形式完成。
class A{
}
class B extends A{
}
class C extends B{
}
Java中不允许多重继承,但是允许多层继承!多层继承一般不会超过三层
1.2.3 在继承时,子类会继承父类的所有结构。
在进行继承的时候,子类会继承父类的所有结构(包括私有属性、构造方法、普通方法)
显示继承:所有非私有操作属于显示继承(可以直接调用)。
隐式继承:所有私有操作属于隐式继承(不可以直接调用,需要通过其它形式调用(get或者set))。
class Person {
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
public Person()
{
System.out.println("父类的构造方法");
}
public void fun()
{
System.out.println("好好学习。");
}
}
class Student extends Person{
private String schoolName;
public String getSchoolName()
{
return schoolName;
}
public void setSchoolName(String schoolName)
{
this.schoolName=schoolName;
}
public Student()
{
System.out.println("子类的构造方法");
}
}
public class Test2{
public static void main(String[] args)
{
Student student=new Student();
student.setName("花花");
student.setAge(18);
//隐式继承
System.out.println("姓名:"+student.getName()+" 年龄:"+student.getAge());
//显示继承
student.fun();
}
}
此时父类中的属性以及方法均被子类所继承,但是发现子类能够使用的是所有非private操作,而所有的private操作无法被直接使用,所以称为隐式继承。
2. 典型例题
class A{
public A()
{
System.out.println("1.A类的构造方法");
}
{
System.out.println("2.A类的构造块");
}
static{
System.out.println("3.A类的静态方法");
}
}
public class B extends A{
public B()
{
System.out.println("4.B类的构造方法");
}
{
System.out.println("5.B类的构造块");
}
static{
System.out.println("6.B类的静态方法");
}
public static void main(String[] args)
{
System.out.println("7.start......");
new B();
new B();
System.out.println("8.end.....");
}
}
主类中的静态块优先于主方法执行,所以6应该在7前面执行,但是B类继承于A类,所以先执行A类的静态块3,所以进主方法前的执行顺序为:3 6
进主方法后执行7,new B()之后应先执行A的构造方法然后执行B的构造方法,但由于A类和B类均有构造块,构造块又优先于构造方法执行即 2 1(A的构造家族) 5 4(B的构造家族),有多少个对象,构造家族就执行几次,题目中有两个对象 所以执行顺序为:3 6 7 2 1 5 4 2 1 5 4 8