目录
继承是什么?
继承:对共性进行抽取,从而实现代码的复用
Dog:子类/派生类
Animal:父类/基类
那么如何在main方法中使用子类呢?
1,子类中访问父类的成员变量
1)子类和父类中不存在同名的变量
class Base{
public int a;
public int b;
}
class Derived extends Base {
public int c;
public void func() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
子类有就拿子类的,子类没有就拿父类的
2)子类和父类成员变量同名
如果父类和子类有相同的成员变量,就先访问自己的
class Base{
public int a;
public int b;
public int c = 10;
}
class Derived extends Base {
public int c = 11;
public void func() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
public class Test03 {
public static void main(String[] args) {
Derived derived = new Derived();
derived.func();
}
运行结果:
总结:
在子类方法中或者通过子类对象访问成员时
如果访问的成员变量中子类中有,优先访问自己的成员变量
如果访问的成立变量子类无,则访问父类继承下来的,如果父类也没有定义,则编译报错
如果访问的成员变量与父类中成员变量同名,则优先访问自己的
成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找
那有人就是反骨一身,说我就想在子类中访问父类的咋办??
那么就要引出一个关键字super
运行结果就变成了:
2,子类中访问父类的成员方法
1)子类和父类方法名称不同
可以直接进行引用
2)子类和父类方法名称相同
和上述的子类和父类成员变量同名一样,都是就近原则
如果非要访问父类的方法就和上述处理一样,加一个super
总结:
通过子类对象访问父类与子类不同方法时,优先在子类中找,找到则访问,找不到则在父类找,找到则访问,找不到那就编译报错
通过子类(派生类)对象访问父类与子类方法同名时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法传递参数选择合适的方法访问,如果没有则报错
简单的来说就是访问方法的时候,现在子类找,如果子类有那么就调用子类的如果没有就去父类找
Super关键字:
super关键字,super关键字主要作用:在子类方法中访问父类的成员
不能在静态方法中使用;和this一样
在子类方法当中访问父类的成员变量和方法
只能指代自己的父类
子类的构造方法
增加了一个带有两个参数的构造方法;然后代码就报错了,为啥捏??
在继承关系上,当我们在构造子类的时候,一定要先帮助父类进行构造
那么怎么帮助?调用构造方法
也可以这样写:
这样写更灵活一点;
注意:这两句代码顺序不能乱!!!
super在子类构造方法内,调用父类构造方法的时候,一定要放在第一行
super和this不能同时出现!!!
当父类和子类都没有提供任何的构造方法的时候
父类会默认提供:
子类会默认提供:
Super和This
相同点:
1,都是Java中的关键字
2,只能在类的非静态方法中使用,用来访问非静态成员方法和字段
3,值构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在
不同点:
1,this是当前对象的引用,当前对象即i调用实例方法的对象,super相当于是子类对象中从父类继承下部分成员的引用
2,在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
3,在构造方法中:this(...)用来调用 本类构造方法,super(..)用来调用父类构造方法,两种调用不能同时在构造方法中出现
4,构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(..)不写就没有
再谈初始化
class Person {
static {
System.out.println("静态的代码块");
}
{
System.out.println("实例代码块");
}
public Person() {
System.out.println("不带参数的构造方法");
}
}
class Man extends Person {
static {
System.out.println("子类的静态代码块");
}
{
System.out.println("子类的实例代码块");
}
public Man() {
System.out.println("子类不带参数的构造方法");
}
}
public class Test04 {
public static void main(String[] args) {
Man man = new Man();
}
}
运行结果:
总结:
静态的大于其他,父类的大于子类
再次运行运行结果:
静态的只执行一次!!!!
那总有一些特殊情况,有的类就是不想被继承那么怎么办?
那就有一个关键字final来修饰就可以啦~
final关键字
此时a就变成了一个常量
public static void main(String[] args) {
final int[] array = {1,2,3};
//array = new int[10];
array[0] = 10;
}
上述代码在内存中是怎样的存在呢??
final在Java中有什么作用?
(1)用来修饰一个引用
如果引用为基本数据类型,则该引用为常量,该值无法修改;
如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改。
如果引用时类的成员变量,则必须当场赋值,否则编译会报错。
(2)用来修饰一个方法
当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。
(3)用来修饰类
当用final修改类时,该类成为最终类,无法被继承。
组合
组合只是一种思想
class Student {
}
class Teacher {
}
class School {
public Student[] students = new Student[3];
public Teacher[] teachers = new Teacher[3];
}
public class Test06 {
public static void main(String[] args) {
School school = new School();
}
}