1.继承
Bird类继承Animal类
由于Animal类有构造方法,因此Bird类内部也需要用super构建一个构造方法
package com.bit.demo1;
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
System.out.println(this.name + "Animal构造方法");
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
/**
* 子类 extends 父类
* 子类:派生类
* 父类:基类,超类
* 1.Java 中使用extends只能单继承[继承一个类]
* 2.对于父类中的private方法或属性,子类无法访问
* 3.子类在构造的时候,要先帮助父类构造
* <p>
* this()-->调用本类其它的构造方法
* this.data-->访问当前类当中的属性
* this.func()-->调用本类的其它成员方法
* <p>
* super()-->调用父类的构造方法
* super.data-->访问父类的属性
* super.func()-->访问父类的成员方法
* <p>
* <p>
* 切忌继承超过3层
* 如果不想让此方法被继承,可用final修饰
* final int a = 0-->常量,只能被初始化一次,接下来就不能再来修改
* final 修饰类: 密封类 特性:不能被继承。一旦一个类被final修饰,那么这个类必然不能被继承
* final 修饰方法:
*/
//class Cat extends Animal {
// public Cat(String name) {
// super(name);//显式调用
// super.name = "qiqi";
// System.out.println(this.name + "Cat(String)");
// }
// /*public String name;
//
// public void eat() {
// System.out.println(this.name + "Cat::eat()");
// }*/
//}
class Bird extends Animal {
public String name;
public Bird(String name) {
super(name);
System.out.println(super.name);
}
public void fly() {
System.out.println(super.name + "正在飞");
}
}
final class Cat extends Animal {
public Cat(String name) {
super(name);
}
}
public class TestDemo {
public static void main(String[] args) {
Bird bird = new Bird("小鸟");
System.out.println(bird.name);
bird.fly();
}
}
2.public,protected,default,private的继承关系
No | 范围 | private | default | protected | public |
---|---|---|---|---|---|
1 | 同一包中的同一类 | √ | √ | √ | √ |
2 | 同一包中的不同类 | √ | √ | √ | |
3 | 不同包中的子类 | √ | √ | ||
4 | 不同包中的非子类 | √ |
我们希望类要尽量做到 “封装”, 即隐藏内部实现细节, 只暴露出 必要 的信息给类的调用者.
因此我们在使用的时候应该尽可能的使用 比较严格 的访问权限. 例如如果一个方法能用 private,
就尽量不要用 public.
另外, 还有一种 简单粗暴 的做法: 将所有的字段设为 private, 将所有的方法设为 public. 不过这种
方式属于是对访问权限的滥用, 还是更希望同学们能写代码的时候认真思考, 该类提供的字段方法
到底给 “谁” 使用(是类内部自己用, 还是类的调用者使用, 还是子类使用)
3.向上转型
package com.bit.demo2;
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
System.out.println("Animal(String)");
}
public void eat() {
System.out.println(this.name + "Animal::eat()");
}
}
class Cat extends Animal {
public int count =99;
public Cat(String name) {
super(name);
System.out.println("Cat(String)");
}
}
class Bird extends Animal {
public String name;
public Bird(String name) {
super(name);
System.out.println(super.name);
}
public void fly() {
System.out.println(super.name + "Bird::fly()");
}
}
public class TestMain {
public static Animal func() {
Cat cat = new Cat("咪咪");
return cat;
}
public static void main(String[] args) {
Animal animal = func();
animal.eat();
}
public static void func(Animal animal){
animal.eat();
}
public static void main3(String[] args) {
Cat cat = new Cat("咪咪");
func(cat);
}
//向上转型
public static void main2(String[] args) {
/*
向上转型: 父类引用 引用子类对象
*/
Animal animal = new Cat("咪咪");
animal.eat();
}
public static void main1(String[] args) {
Animal animal = new Animal("豆豆");
Cat cat = new Cat("咪咪");
// animal.count;//error: 向上转型之后,通过父类的引用 只能访问父类自己的方法或者属性。父类引用只能访问自己的
}
}
4.区分重写和重载
package com.bit.demo3;
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
System.out.println("Animal(String)");
}
public void eat() {
System.out.println(this.name + "Animal::eat()");
}
}
class Cat extends Animal {
public int count = 99;
public Cat(String name) {
super(name);
System.out.println("Cat(String)");
}
public void eat() {
/*
重载: overload
方法名相同
参数列表不同(参数的个数+类型)
返回值不做要求
同一个类中
重写: override
方法名相同
返回值相同
参数列表相同
不同的类-->继承关系上
注意事项:
1.需要重写的方法不能是被final修饰的。被final修饰之后,他是密封方法,不可以修改
2.被重写的方法,访问修饰限定符一定不能是私有的
3.被重写的方法,子类当中的访问修饰限定夫要大于等与父类的修饰访问限定符【private < default < protected < public
4.static修饰的方法不能被重写
*/
System.out.println(this.name + "重写Cat::eat()");
}
}
class Bird extends Animal {
public String name;
public Bird(String name) {
super(name);
System.out.println(super.name);
}
public void fly() {
System.out.println(super.name + "Bird::fly()");
}
}
public class TestMain {
/*
多态
运行时绑定【动态绑定】
父类引用 引用子类对象,同时 通过父类引用调用同名的覆盖方法
此时就会发生运行时绑定
反编译Java代码
D:\Progam\jetBrains\IDEA\高博\src\com\bit\demo3>javac -encoding utf8 TestMain.java
D:\Progam\jetBrains\IDEA\高博\src\com\bit\demo3>javap -c TestMain
警告: 二进制文件TestMain包含com.bit.demo3.TestMain
Compiled from "TestMain.java"
public class com.bit.demo3.TestMain {
public com.bit.demo3.TestMain();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class com/bit/demo3/Cat
3: dup
4: ldc #3 // String 咪咪
6: invokespecial #4 // Method com/bit/demo3/Cat."<init>":(Ljava/lang/String;)V
9: astore_1
10: aload_1
11: invokevirtual #5 // Method com/bit/demo3/Animal.eat:()V
14: return
}
1: invokespecial #1 // Method java/lang/Object."<init>":()V 【运行--》这里代表调用了构造方法】
11: invokevirtual #5 // Method com/bit/demo3/Animal.eat:()V 【编译--》代表调用方法了。非静态方法】
*/
public static void main(String[] args) {
Animal animal = new Cat("咪咪");
animal.eat();
}
}
5.向下转型,动态绑定那些坑
package com.bit.demo4;
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
System.out.println("Animal(String)");
eat();
}
public void eat() {
System.out.println(this.name + "Animal::eat()");
}
}
class Cat extends Animal {
public int count = 99;
public Cat(String name) {
super(name);
System.out.println("Cat(String)");
}
public void eat() {
System.out.println(this.name + "重写Cat::eat()");
}
}
class Bird extends Animal {
public String name;
public Bird(String name) {
super(name);
}
public void fly() {
System.out.println(super.name + "Bird::fly()");
}
}
public class TestMain {
/*
一个坑:类的在构造方法中调用时可以发生运行时绑定
*/
public static void main(String[] args) {
Cat cat = new Cat("嘻嘻");
// cat.eat();
}
// 不安全的向下转型: 猫不能bird化
public static void main2(String[] args) {
Animal animal = new Cat("咪咪");
/*Bird cat = (Bird) animal;
cat.fly();*/
/*
instance解决
A instance B
判断A 是不是 B的一个类
*/
if (animal instanceof Bird) {
Bird cat = (Bird) animal;
cat.fly();
} else {
System.out.println("向下转型之间不是同一个类");
}
}
public static void main1(String[] args) {
/*
向下转型
注意:非常不安全,很少使用
*/
Animal animal = new Bird("八哥");
animal.eat();
// 向下转型-->父类的引用赋值给了子类
Bird bird = (Bird) animal;
bird.fly();
}
}