✨欢迎关注🖱点赞🎀收藏⭐留言✒
🔮本文由京与旧铺原创,csdn首发!
😘系列专栏:java学习
💻首发时间:🎞2022年10月18日🎠
🎨你做三四月的事,八九月就会有答案,一起加油吧
🀄如果觉得博主的文章还不错的话,请三连支持一下博主哦
🎧最后的话,作者是一个新人,在很多方面还做的不好,欢迎大佬指正,一起学习哦,冲冲冲
💬推荐一款模拟面试、刷题神器👉[点击进入网站
1.组合
在继承的关系中,子类(导出类)与父类(基类,超类)的关系是is - a
的关系,比如就鸟(子类)继承动物(父类),可以说鸟是一种动物。 而对于组合,就是在一个新类中使用一个或多个类,比如我们要创建一个学校类,我们都知道学校有老师,有学生,而且一般情况下肯定不止一个,所以学校类中会使用学生类和老师类,也就是说组合是hava
的关系,也就是学校里面有老师和学生。
class Student {
public String name;
public double score;
public int age;
public int classNo;
}
class Teacher {
public String name;
public int age;
public int classNo;
public String subject;
}
public class School {
public Student[] stu;
public Teacher[] tec;
}
复制代码
2.多态
2.1向上转型
向上转型的前提是类之间存在继承关系,使用父类引用指向子类对象,这就叫做向上转型。 就比如Bird类继承了Animal类,然后使用父类Animal引用指向子类Bird对象,在Java中是允许父类引用指向子类对象的,过程中发生了向上转型,但是要注意向上转型后父类引用只能访问父类的成员变量和方法(子类没有重写父类方法的情况下),就栗子来说,Animal animal = new Bird("小鸟", 2);
这个animal引用只能访问eat方法,不能访问子类Bird的fly方法。
class Animal {
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(this.name + "正在吃饭!");
}
}
class Bird extends Animal{
public Bird(String name, int age) {
super(name, age);
}
public void fly() {
System.out.println(this.name + "正在飞翔!");
}
}
public class UpClass {
public static void main(String[] args) {
Animal animal = new Bird("小鸟", 2);
animal.eat();
}
}
复制代码
⭐️常见发生向上转型有三种情况:
- 将子类对象的地址传给父类引用。
- 将子类对象的地址以参数形式传递给父类类型的形参。
- 在返回值为父类引用类型的方法中,将子类对象的地址作为返回值。
class Animal {
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(this.name + "正在吃饭!");
}
}
class Bird extends Animal{
public Bird(String name, int age) {
super(name, age);
}
public void fly() {
System.out.println(this.name + "正在飞翔!");
}
}
public class UpClass {
public static void func1(Animal an) {
an.eat();
}
public static Animal func2() {
return new Bird("小鸟", 2);
}
public static void main(String[] args) {
Animal animal1 = new Bird("小鸟", 2);
animal1.eat();
func1(new Bird("小鸟", 2));
Animal animal2 = func2();
animal2.eat();
}
}
复制代码
2.2运行时绑定
2.2.1概念
运行时绑定也称动态绑定,它是在程序运行时所发生的一种行为。发生运行时绑定是基于向上转型的,所谓运行时绑定就是通过父类引用调用父类与子类同名的覆盖(重写/覆写)方法。为什么叫做运行时绑定呢?因为在程序运行的时候,方法的重写才发生,我们来看看一个含有重写代码的编译后的反汇编,会发现编译后调用的还是父类的方法。
class Animal {
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(this.name + "正在吃饭!");
}
}
class Bird extends Animal{
public Bird(String name, int age) {
super(name, age);
}
public void fly() {
System.out.println(this.name + "正在飞翔!");
}
@Override
public void eat() {
System.out.println(this.age + this.name + "正在慢慢地吃饭!");
}
}
class Cat extends Animal{
public Cat(String name, int age) {
super(name, age);
}
public void cute() {
System.out.println(name + "忙着装可爱!");
}
@Override
public void eat() {
System.out.println(this.age + this.name + "正在安静地吃饭!");
}
}
public class OverFunc {
public static void main(String[] args) {
Animal animal1 = new Bird("小鸟", 2);
animal1.eat();
Animal animal2 = new Cat("小猫", 1);
animal2.eat();
}
}
复制代码
2.2.2重写方法
重写又称覆写,覆盖,顾名思义就是使用一个方法覆盖/覆写/重写了一个方法,但是不是任意两个方法都能发生重写,发生重写是有要求的,就像方法重载一样,都有着特定的规定,重写方法是在子类当中的,父类中的方法是被重写方法。
⭐️方法重写的条件:
- 方法名相同
- 参数列表相同(包括形参个数与形参类型)
- 返回值类型相同(协变返回类型除外)
协变返回类型指的是子类中的成员函数的返回值类型不必严格等同于父类中被重写的成员函数的返回值类型,而可以是更 "狭窄" 的类型。比如,子类与父类类型的返回值就有这样的关系。
⭐️方法重写注意事项:
- static修饰的方法不能重写。
- final修饰的方法不能重写。
- 权限为private的方法不能重写。
- 子类重写父类方法时,子类中重写的方法访问权限必须大于等于父类中被重写的方法。
知道了方法的重写我们来看看前面那个程序是否真如我们所说的,在运行时发生了重写。
结果是调用了子类的eat,说明重写是在程序运行时发生的,程序编译并没有发生重写。
评论(0)