当前位置:   article > 正文

【JavaSE】解密 继承和多态(下)

【JavaSE】解密 继承和多态(下)

前言

紧接着上篇 解密继承和多态(上)~

欢迎关注个人主页:逸狼


创造不易,可以点点赞吗~

如有错误,欢迎指出~



目录

前言

protected关键字

在同一包下同一类可以访问

代码理解

在同一包下不同类可以访问

代码理解

在不同包下的子类可以访问

代码理解

再谈访问权限问题

final关键字

final修饰变量

final修饰类

组合

代码举例

多态

动态绑定

发生条件

向上转型

代码理解

直接赋值

方法传参

作为返回值 

向下转型

父类和子类 方法的重写

要求

注意

@Override

与代码重载的区别

代码理解


protected关键字

接下来我们谈谈protected关键字

在同一包下同一类可以访问

代码理解

如下的代码,用protected修饰c,在同一个包demo1下的同一类Test1下,func方法可以成功访问c

  1. package demo1;
  2. public class Test1 {
  3. public int a;
  4. protected int c=99;
  5. public void func(){
  6. System.out.println(c);
  7. }
  8. }

在同一包下不同类可以访问

在同一个包demo1下面再建一个类TestProtected1

代码理解

调用Test1产生实例化对象test1,可以通过对象test1访问Test1类下的成员c

  1. package demo1;
  2. public class TestProtected1 {
  3. public static void main(String[] args) {
  4. Test1 test1=new Test1();
  5. System.out.println(test1.c);
  6. }
  7. }

在不同包下的子类可以访问

被protected修饰,不管同不同包,只要是子类就都可以 通过super 访问

代码理解

新创建另外一个包demo2,再在下面创建一个类Test2

在Test2类中可以通过super成功访问不同包demo2下Test1类中被protected修饰的c

前提:被继承的类是用public修饰的,在代码中体现就是Test被public修饰了才行

(其中类的权限 只有 两种:一个是用public修饰的,另一个是不用public修饰的)

  1. package demo2;
  2. import demo1.Test1;//要先导包
  3. //继承Test1
  4. public class Test2 extends Test1 {
  5. public void test(){
  6. System.out.println(super.c);
  7. }
  8. public static void main(String[] args) {
  9. // System.out.println(super.c);//会报错,因为main方法中有static修饰,不能用super
  10. }
  11. }

再谈访问权限问题

在上一篇我们讲解了private和public的范围,他们是访问权限的两个极端

  • private只能在同一包的同一类下访问
  • public是 不管是否同包 不管是否同类 都能被访问

我们可以用下图总结

这里的default不是关键字,表示的是在成员变量前不加任何public、private等关键字

Java不支持多继承

final关键字

final修饰变量

final int SIZE=10;表示SIZE变成常量(不能被修改)

final修饰类

final用于控制继承,被final修饰的类 表示 当前类不可以被继承,此时这个类称为密封类

组合

组合是代码层面的一种写法,是has-a的关系(例如 汽车中的零部件组合成了一辆汽车),仅仅是将一个类的示例作为另一个类的成员变量

代码举例

老师类和学生类组合成了学校类

  1. class Teacher{
  2. }
  3. class Student{
  4. }
  5. class School{
  6. private Teacher[] teachers;
  7. private Student[] students;
  8. }

多态

同一件事不同的对象上产生的效果是不一样

代码理解

当Animal引用的对象不一样(animal1和animal2),调用eat方法,表现出的行为不一样时(Animal1吃狗粮,Animal2吃鸟粮),这就叫做 多态。

  1. class Animal{
  2. public String name;
  3. public int age;
  4. public void eat(){
  5. System.out.println(this.name+" 正在吃~");
  6. }
  7. public Animal(String name, int age) {
  8. this.name = name;
  9. this.age = age;
  10. }
  11. }
  12. class Dog extends Animal{
  13. //Alt键 加上 Enter键快速生成子类构造方法
  14. public Dog(String name, int age) {
  15. super(name, age);
  16. }
  17. @Override//注解 用于帮助检查方法重写是否正确,若重写的方法有问题,他就会报错
  18. public void eat(){
  19. System.out.println(this.name+"正在吃狗粮~");//与父类的eat形成 方法的重写
  20. }
  21. public void bark(){
  22. System.out.println(this.name+" 正在汪汪汪~");
  23. }
  24. }
  25. class Bird extends Animal{
  26. public Bird(String name, int age) {
  27. super(name, age);
  28. }
  29. public void qiqi(){
  30. System.out.println(this.name+" 正在吱吱吱~");
  31. }
  32. public void eat(){
  33. System.out.println(this.name+"正在吃鸟粮~");//与父类的eat形成 方法的重写
  34. }
  35. }
  36. public class Test {
  37. public static void func(Animal animal){
  38. }
  39. public static Animal func2(){
  40. return new Dog("旺财",3);
  41. }
  42. public static void main(String[] args) {
  43. /* Dog dog=new Dog();
  44. Animal animal=dog;//向上转型*/
  45. Animal animal1=new Dog("旺财",3);//向上转型
  46. animal1.eat();
  47. Animal animal2=new Bird("小蜂",1);
  48. animal2.eat();
  49. //animal1.bark();//会报错,因为Animal中没有bark方法,通过父类引用只能访问父类自己的有的
  50. }
  51. }

实现多态的前提是动态绑定~

动态绑定

编译的是父类方法,但是调用的是子类方法

代码理解

编译用的父类Animal中的eat方法,但结果是调用的是子类eat方法

  1. Animal animal1=new Dog("旺财",3);//向上转型
  2. animal1.eat();

 代码结果

发生条件

父类引用子类对象【向上转型】

通过父类引用 调用重写的方法【方法的重写】

向上转型

实际就是创建一个子类对象,将其当成父类对象来使用。

语法格式:父类类型 对象名 = new 子类类型()

  • 优点:让代码实现更简单灵活。
  • 缺陷:不能调用到子类特有的方法。

发生向上转型的时机有三种,通过以下代码加以理解

代码理解
直接赋值
  1. public static void main(String[] args) {
  2. /* Dog dog=new Dog();
  3. Animal animal=dog;//向上转型*/
  4. Animal animal1=new Dog("旺财",3);//向上转型
  5. }
方法传参
  1. public static void func(Animal animal){
  2. }
作为返回值 
  1. public static Animal func2(){
  2. return new Dog("旺财",3);
  3. }

向下转型

  1. Animal animal1=new Dog("旺财",3);//向上转型
  2. Dog dog=(Dog)animal1;//向下转型 要将对象animal1强转成Dog类,否则会报错
  3. //因为 不是所有的动物都是狗
父类和子类 方法的重写

重写又叫覆盖、覆写

要求
  • 方法名相同
  • 方法的参数列表相同(个数、顺序、类型)
  • 方法返回值相同
注意
  • 静态方法 不能 被重写
  • 被private修饰的 不能 被重写
  • 被final修饰的 不能 被重写
  • 如果方法被重写,子类的访问权限要 大于等于 父类的权限
@Override

修饰该方法,说明该方法是重写的

与代码重载的区别

代码理解
  1. //父类Animal中的eat方法
  2. public void eat(){
  3. System.out.println(this.name+" 正在吃~");
  4. }
  5. //子类Dog中的eat方法
  6. public void eat(){
  7. System.out.println(this.name+"正在吃狗粮~");//与父类的eat形成 方法的重写
  8. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/366452
推荐阅读
相关标签
  

闽ICP备14008679号