类和对象进阶 - 继承
1. 继承
1.1 继承解决了什么问题 ? java中如何实现继承 ?
对类的共性进行抽取 对代码进行复用 java中, 使用extends关键字 关联
查看代码
/*
class Dog {
public String name;
public int age;
public float weight;
public void eat() {
System.out.println(name + "正在吃饭");
}
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
class Cat {
public String name;
public int age;
public void eat() {
System.out.println(name + "正在吃饭");
}
public void sleep() {
System.out.println(name + "喵叫");
}
}*/
// 发现上述代码 有很多重复的地方
// 继承用来 复用代码
//
class Animal {
public String name;
public int age;
public void eat() {
System.out.println(name + "正在吃饭");
}
}
class Dog extends Animal{
public String color;
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
class Cat extends Animal{
public void sleep() {
System.out.println(name + "喵叫");
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "小白";
System.out.println(cat.name);
Dog dog = new Dog();
dog.name = "大黄";
System.out.println(dog.name);
}
}
1.2 子类继承父类什么 ? 子类对象如何存储 ?
子类继承父类的成员变量和方法,除了父类构造方法和父类中的静态成员
查看代码
class Animal {
public String name;
public int age;
public static int id = 1;
public void eat() {
System.out.println(name + "正在吃饭");
}
}
class Dog extends Animal{
public String color;
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "a";
dog.age = 2;
}
}

分为两块 一部分存储父类的 一部分存储子类自己的

1.3 访问优先级
子类与父类存在同名成员时,优先访问子类自己的成员变量/方法如果访问的成员方法子类中无,则访问父类继承下来的如果父类也没有定义,则编译报错
查看代码
class Base {
public int a = 1;
public int b = 2;
public void test() {
System.out.println("Base::test()");
}
}
class Derived extends Base {
public int a = 10;
public int c = 3;
public void test() {
System.out.println("Derived::test()");
}
public void test2() {
System.out.println("Derived::test2()");
}
public void test(int a) {
System.out.println(a);
}
public static void main(String[] args) {
Derived derived = new Derived();
// 存在同名成员时,优先访问子类自己的成员变量 / 方法
// 访问的成员方法子类中无,则访问父类继承下来的
// 如果父类也没有定义,则编译报错
System.out.println(derived.a);
derived.test();
derived.test2();
}
}
1.4 super关键字
super 表示父类数据对象的引用, 用来指定访问 父类成员
this 表示对象的引用

查看代码
class Base {
public int a = 1;
public int b = 2;
public void test() {
System.out.println("Base::test()");
}
}
class Derived extends Base {
public int a = 10;
public int c = 3;
public void test() {
System.out.println("Derived::test()");
}
public void test2() {
System.out.println("Derived::test2()");
}
public void test(int a) {
System.out.println(a);
}
public void method() {
// super this
System.out.println(this.a);
System.out.println(super.a);
}
public static void main(String[] args) {
Derived derived = new Derived();
derived.method();
}
}
super关键字总结与注意事项
总结:
1. super用来在子类中 指定访问父类成员变量和方法 因为this引用优先访问子类自己的成员
2. super加点号 访问父类成员变量和方法
3. super(..) 访问父类的构造方法
注意事项:
1. super只能在非静态方法中使用
2. 在子类构造方法中调用super(...)初始化父类成员,必须放在第一行
super与this 相同点和不同点
相同点:
1. 都是Java中的关键字
2. 只能在类的非静态方法中使用
3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在
不同点:
1. this是当前对象的引用 —— super 是从父类继承下的部分成员变量的引用 如图

2. 在非静态成员方法中,this优先访问子类自己的成员变量和属性 如果找不到子类成员 再去访问父类成员 —— super 指定访问父类的成员
3. 在子类构造方法中,this(...)用于调用子类自己的构造方法,super(...)用于调用父类构造方法,两种调用不能同时在构造方法中出现 因为this() super()都需要占用第一行
4. 子类构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...)调用用户不写则没有
1.5 子类对象如何初始化 ?
首先调用父类构造方法给子类对象中的父类成员进行初始化
然后再初始化子类自己的成员
class Animal {
public String name;
public int age;
public void eat() {
System.out.println(name + "正在吃饭");
}
public Animal(String name,int age) {
this.name = name;
this.age = age;
}
}
class Dog extends Animal{
public String color;
public Dog(String name,int age) {
// 在子类自己成员变量初始化前 必须先调用父类构造初始化子类对象中的父类成员
super(name,age);
this.color = "黑色";
}
public static void main(String[] args) {
Dog dog = new Dog("a",1);
System.out.println(dog.name);
}
}
为什么自己没写构造,编译器不报错 ?
class Animal {
public String name;
public int age;
public void eat() {
System.out.println(name + "正在吃饭");
}
// 默认生成 Animal构造
/*public Animal() {
}*/
}
class Dog extends Animal{
public String color;
// 默认生成 Dog构造
/*public Dog() {
自动生成 super()
super();
}*/
public static void main(String[] args) {
Dog dog = new Dog();
}
}
1.6 继承关系上的执行顺序
父类的静态,子类的静态,父类的实例,父类的构造,子类的实例,子类的构造
class Animal {
public String name;
public int age;
public Animal() {
System.out.println("Animal()");
}
static {
System.out.println("Animal::static{}");
}
{
System.out.println("Animal::{ }");
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Animal(String name, int age)");
}
public void eat() {
System.out.println(this.name+"正在吃.....");
}
}
class Dog extends Animal {
public String color;
public Dog() {
//super();
System.out.println("Dog()");
}
static {
System.out.println("Dog::static{}");
}
{
System.out.println("Dog::{ }");
}
public static void main(String[] args) {
Dog dog = new Dog();
}
}
1.7 java继承关系与final修饰类


2. 访问修饰限定符

class Person implements Cloneable {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException{
// 一定得在子类方法中, 调用protected修饰的父类成员
return super.clone();
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person("a",1);
Person p2 = (Person) person1.clone();
System.out.println(p2.name);
}
}
浙公网安备 33010602011771号