Java 第四天 继承
1.1 为什么要使用继承
我们使用对象用来存储数据,要想使用对象首先得有类。在一个项目中,可能有很多数据需要我们存储
例如:存储狗的信息 猫的信息 人的信息 等等 不同的信息需要不同的类去创建不同的对象
假如现在需要创建狗类 : 编号 名字 价格 猫类:编号 名字 品种
此时你就去完成这个操作
public class Dog {
int id;
String name;
double price;
}
public class Cat {
int id;
String name;
String type;
}
当你完成了,过了很久,此时需要把 id 和 name 换成animalID animalName
此时你需要一个一个的都换(假如有一万个)
public class Dog {
int animalID;
String animalName;
double price;
}
public class Cat {
int animalID;
String animalName;
String type;
}
这个操作太麻烦(不嫌弃麻烦的 面向过程思想 java是一种面向对象语言-java支持面向对象思想的那些语法)所以我们需要优化一波
所以我们希望达到的效果: 创建狗类 : 编号 名字 价格 猫类:编号 名字 品种 并且后期如果要修改 改一次全都改完
所以他们就创造了一个语法 能满足你的需求 后来将这个语法命名为 继承
1.2 使用继承语法解决问题
A 创建一个新的类 Animal
B 在Animal中添加成员变量 (多个类共有的)
C 狗猫不再写 id name 共有的内容
D 狗猫继承于Animal
public class Animal {
int id;
String name;
}
public class Cat extends Animal{
String type;
}
public class Dog extends Animal{
double price;
}
public class JavaTest {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.id = 666;
d1.name = "旺财";
d1.price = 66645;
Cat c1 = new Cat();
c1.id = 777;
c1.name = "威廉";
c1.type = "狸花猫";
}
}
1.3 内存模型
1.4 继承语法规则
1 继承使用 extends 关键字
public class Cat extends Animal{
String type;
}
2 java中类的关系(提问:java中是单继承还是多继承)
类 类 继承关系 单继承
类 接口 实现关系 多实现 (弥补java单继承的局限性 因为java刚造出来的时候 吹牛说 我们基于c++并且摒弃了c++中晦涩难懂的多继承多指针的概念)
接口 接口 继承关系 多继承
Class cannot extend multiple classes
public class Cat extends Animal,People{
String type;
}
3 类和类之间建立继承关系 则子类可以访问父类权限达到的内容
提问:私有的可以被继承吗?
不可以 因为私有的无法被子类访问 可以 但是私有的不能被子类访问
4 一个类不写extends 默认继承Object(祖宗类 基类 超类)
验证规则:Animal没有写继承 但是可以调用notify () 此时证明其继承于Object
public static void main(String[] args) {
Animal a1 = new Animal();
a1.notify();
}
提问: Object 有哪些函数 各自的作用
/**
* Class {@code Object} is the root of the class hierarchy.
* Every class has {@code Object} as a superclass. All objects,
* including arrays, implement the methods of this class.
*
* @author unascribed
* @see java.lang.Class
* @since JDK1.0
*/
public class Object {}
5 子类和父类函数调用顺序:本类有先调用本类的 本类没有则调用父类的
此时就有疑问了,继承本来就是父类有 子类可以直接用,现在有一个问题?父类有一个eat函数 子类为什么还要有一个eat函数? (为什么需要重写 或者说 什么时候重写)
在java中 父类有了 子类如果再写一个一样的称之为 函数的重写 英文名字 voerride
父类的函数满足不了子类的需求 所以子类可以对父类函数进行重写 此时调用顺序就起作用了
public static void main(String[] args) {
Animal a = new Animal();
a.id = 666;
a.name = "阿斯蒂芬";
System.out.println(a);
}
此时我们输出a 打印的是com.aaa.day02.test4.Animal@1540e19d 为什么是这个呢?
当我们输出对象的时候 会调用其 toString函数 首先会去Animal类中找 是否有 toString ,发现没有,则调用其父类的,Animal没有写extends关键字 所以其直接继承Object ,所以就去Object中找toString ,发现有
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
则调用,所以输出的是com.aaa.day02.test4.Animal@1540e19d ,但是父类的toString 输出的形式 满足不了Animal的需求 因为Animal想输出自己成员变量的值,所以Animal需要重写父类的toString,重写之后 自己本类有 则调用本类的
在java中 为了防止重写的时候 重写失败 所以造了一个@Override 注解 用来验证当前函数是否对父类重写成功
public class Animal {
public void hello(){}
}
public class Dog extends Animal{
@Override Method does not override method from its superclass
public void hell0(){}
}
6 继承中会产生多态
public class Animal {
public void eat(){
System.out.println("動物都愛吃飯");
}
}
public class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗愛吃肉");
}
}
public static void main(String[] args) {
Animal d1 = new Dog();
d1.eat();
}
这样的写法 有个好听的名字 叫做 多态。
7 super() super
super()代表调用父类公共无参数的构造函数 这句代码在构造函数的第一句 不写默认生成 写了就必须第一句
super 代表 super()创建出来的父类对象
this 代表当前类的对象
this()
public class Animal {
public Animal(){
System.out.println("動物被創建了");
}
}
public class Dog extends Animal{
public Dog(){
int a = 10;
super(); // Call to 'super()' must be first statement in constructor body
System.out.println("狗被創建了");
}
}
此时我们得到一结论: 创建对象的时候 首先会创建一个父类对象 再创建自己类的对象
面试题:
public class Animal {
int age;
public Animal(int age){
this.age = age;
}
}
public class Dog extends Animal{}
代码会报错:
There is no default constructor available in 'com.aaa.day02.test4.Animal'
此时这几个关键字 就体现了继承的原理