• 7.java三大特征之一:多态


    ①封装

    将属性和方法书写到类里面的操作就是封装

    封装可以为属性和方法添加私有权限

    ②继承

    子类默认继承父类的所有属性和方法

    子类可以重写父类属性和方法

    ③多态

    传入不同的对象,产生不同的结果

    重写

    1. package extend;
    2. public class Test {
    3. public static void main(String[] args) {
    4. Dog dog = new Dog();
    5. dog.cry();
    6. }
    7. }
    8. class Animal{
    9. public Object cry() {
    10. System.out.println("动物叫");
    11. return null;
    12. }
    13. }
    14. class Dog extends Animal{
    15. public String cry() {
    16. System.out.println("狗叫");
    17. return null;
    18. }
    19. }

    重载与重写的区别

    多态

    对象的多态

    引入代码

    1. public class Test {
    2. public static void main(String[] args) {
    3. Master master = new Master();
    4. master.name = "ljw";
    5. Dog dog = new Dog();
    6. dog.name = "大黄";
    7. Bone bone = new Bone("骨头");
    8. master.feed(dog,bone);
    9. Cat cat = new Cat();
    10. cat.name = "tom";
    11. Fish fish = new Fish("带鱼");
    12. master.feed(cat,fish);
    13. }
    14. }
    15. class Master{
    16. String name;
    17. public void feed(Dog dog,Bone bone){
    18. System.out.println(name+"给 "+dog.name+" 吃 "+bone.name);
    19. }
    20. public void feed(Cat cat,Fish fish){
    21. System.out.println(name+" 给 "+cat.name+" 吃 "+fish.name);
    22. }
    23. }
    24. class Food{
    25. String name;
    26. }
    27. class Bone extends Food{
    28. String name;
    29. public Bone(String name){
    30. this.name = name;
    31. }
    32. }
    33. class Fish extends Food{
    34. String name;
    35. public Fish(String name){
    36. this.name = name;
    37. }
    38. }
    39. class Animal{
    40. String name;
    41. public Object cry() {
    42. System.out.println("动物叫");
    43. return null;
    44. }
    45. }
    46. class Dog extends Animal{
    47. public String cry() {
    48. System.out.println("狗叫");
    49. return null;
    50. }
    51. }
    52. class Cat extends Animal{
    53. public String cry() {
    54. System.out.println("猫叫");
    55. return null;
    56. }
    57. }

    编译时类型和运行时类型

    Java的引用变量有两个类型,一个是编译时类型,一个是运行时类型,栈中存放的是一些引用和一些变量,而堆内存中存放的是对象。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。

    Person p=new Women()(Women类继承自Person类)

    假如p的属性修饰符为public 访问属性时得到的是Person类的属性还是Women类的属性,方法调用又是哪个类?

    答案:会得到Person类的属性,调用Women类的方法。

    编译时类型

    编译时,JVM会在栈中静态创建基本数据变量,和引用数据变量的引用,回到刚刚那句代码,显然,p这个引用就是在编译时创建的,那么,p的编译时类型就是Person了。

    编译时期可以理解为堆内存中还没有为该对象创建内存,只是在栈中创建了一些基本类型的变量和引用,所以编译时类型就是指在new该对象之前被加载到栈中的属性或方法。

    运行时类型

    当运行这句java代码时,JVM在堆中为p新建一块内存,对应new Women()这句代码,所以p的运行时类型就是Women

    运行时类型,是指new了一个对象出来,在栈中为该对象分配了内存,此时的运行时类型也就是栈中对象的属性或方法了。

    Person person = new student();

    这里就可以很好地理解编译时类型和运行时类型了。编译时类型是Person,当new了一个对象之后,堆内存中产生了一个Student对象,此时的类型就是运行时类型,也就是Student类型了。

    如果编译时类型和运行时类型不一致,会出现所谓的多态。因为子类其实是一种特殊的父类,因此java允许把一个子类对象直接赋值给一个父类引用变量,无须任何类型转换,

    或者被称为向上转型,由系统自动完成。

    1. public class Test {
    2. public static void main(String[] args) {
    3. Animal dog = new Dog();
    4. dog.cry();
    5. }
    6. }
    7. class Animal{
    8. public Object cry() {
    9. System.out.println("动物叫");
    10. return null;
    11. }
    12. }
    13. class Dog extends Animal{
    14. public String cry() {
    15. System.out.println("狗叫");
    16. return null;
    17. }
    18. }
    1. package extend;
    2. public class Test {
    3. public static void main(String[] args) {
    4. Master master = new Master();
    5. master.name = "ljw";
    6. Animal dog = new Dog("大黄");
    7. Food bone = new Bone("骨头");
    8. master.feed(dog,bone);
    9. Animal cat = new Cat("tom");
    10. Food fish = new Fish("带鱼");
    11. master.feed(cat,fish);
    12. }
    13. }
    14. class Master{
    15. String name;
    16. public void feed(Animal animal,Food food){
    17. System.out.println(name+"给 "+animal.name+" 吃 "+food.name);
    18. }
    19. }
    20. class Food{
    21. String name;
    22. }
    23. class Bone extends Food{
    24. public Bone(String name){
    25. this.name = name;
    26. }
    27. }
    28. class Fish extends Food{
    29. public Fish(String name){
    30. this.name = name;
    31. }
    32. }
    33. class Animal{
    34. String name;
    35. public Object cry() {
    36. System.out.println("动物叫");
    37. return null;
    38. }
    39. }
    40. class Dog extends Animal{
    41. public Dog(String name){
    42. this.name = name;
    43. }
    44. public String cry() {
    45. System.out.println("狗叫");
    46. return null;
    47. }
    48. }
    49. class Cat extends Animal{
    50. public Cat(String name){
    51. this.name = name;
    52. }
    53. public String cry() {
    54. System.out.println("猫叫");
    55. return null;
    56. }
    57. }

    向上转型

    父类 父类对象 = new 子类();

    1. package extend;
    2. public class Test {
    3. public static void main(String[] args) {
    4. Animal animal = new Dog();
    5. animal.cry();
    6. // animal.a();
    7. }
    8. }
    9. class Animal{
    10. public void cry() {
    11. System.out.println("动物叫");
    12. }
    13. }
    14. class Dog extends Animal{
    15. public void a() {
    16. System.out.println("狗叫");
    17. }
    18. }

    向下转型

    1. public class Test {
    2. public static void main(String[] args) {
    3. Animal animal = new Dog();
    4. animal.cry();
    5. //!!要和 ^^^这个一样
    6. Dog dog = (Dog) animal;
    7. dog.a();
    8. }
    9. }
    10. class Animal{
    11. public void cry() {
    12. System.out.println("动物叫");
    13. }
    14. }
    15. class Dog extends Animal{
    16. public void a() {
    17. System.out.println("狗叫");
    18. }
    19. }

    java多态中 方法看运行类型 属性看编译类型 方法重写属性不重写

    1. package extend;
    2. public class Test {
    3. public static void main(String[] args) {
    4. Animal animal = new Dog();
    5. animal.cry();
    6. System.out.println(animal.age);
    7. }
    8. }
    9. class Animal{
    10. int age = 10;
    11. public void cry() {
    12. System.out.println("动物叫");
    13. }
    14. }
    15. class Dog extends Animal{
    16. int age = 111;
    17. public void cry() {
    18. System.out.println("狗叫");
    19. }
    20. }

    instanceof:看该对象的运行时类型是否为xx类型或他的子类型

  • 相关阅读:
    美国政府首席信息安全官详细介绍零信任战略竞赛
    【IoT】公众号“简一商业”更名为“产品人卫朋”说明
    Yolov5 训练自已的数据集 详细图文操作(全)
    一种改进Harris算子的角点特征检测研究-含Matlab代码
    Apipost自动化测试
    Node.js 入门教程 26 npm 依赖与开发依赖 & 27 Node.js 包运行器 npx
    java计算机毕业设计ssm+vue企业后勤订餐管理系统
    《设计模式》之单例模式
    threejs学习100问
    这款IDE插件3.0让你成为公司最懂安全的程序员
  • 原文地址:https://blog.csdn.net/m0_61983575/article/details/127897627