面向对象的三大特征

万物皆可归类,类是对于世界事物的高度抽象,不同的事物有不同的关系:一个类自身与外界的封装关系;一个父类与子类的继承关系;一个类和多个类的多态关系。

万物皆对象,对象是具体的世界事物,面向对象的三大特征:封装、继承、多态,封装说明一个行为和属性与其他的类的关系,继承是父类和子类的关系,多态是类与类之前的关系

封装

概念

封装就是把抽象的数据(属性)和对数据的操作(方法)封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作,才能对数据进行操作

理解和好处

1、封装隐藏了实现细节,类的内部机制实现不会呈现,细节是写方法的人考虑的,而外部只需要传入必要的参数实现操作就可以了

2、封装可以对数据进行验证,保证合理性

Person p = new Person();
p.name = "jack";
p.age = 1000;

显而易见,不合理的地方是年龄,不封装时可以对数据进行修改,并且系统并不会发现其不合理,而封装就是在方法内部对数据的验证和处理

3、可以在不影响使用的情况下改变类的内部结构,同时保护了内部数据。一个类内部中,通常会对其属性进行私有化private,所以不能直接修改属性,而提供了公有的set方法,可以对数据进行判断和处理,而属性私有化后,外部无法访问,又提供了get方法,用于对数据进行获取

继承

概念

继承是从已有类中派生出新的类,新的类能吸收已有类的数据属性和方法,并且扩展新的能力,不用再重新写已有类的属性和方法,直接继承即可。通过extends关键字来实现继承

好处

1、继承避免了对于一般类和特殊类之间的共同特征进行的重复的特征描写,通过继承可以清晰得表达每一项共同特征所适应的概念范围,在一般类中定义的属性和方法适用于这个类本身以及这个类以下的每一层特殊类的全部对象。通过继承原则使得系统模型比较简练和清晰

对于小学生、中学生和大学生共有的属性,姓名、年龄、性别等属性可以写在一个父类中,而小学生类使用时直接通过extends来获取,不需要再重写

//student类
public class Student {public String name;public int age;public void setAge(int age) {this.age = age;}public void show(){System.out.println("学生名:"+name+"年龄:"+age);}
}
//子类pupil
public class Pupil extends Student{public void testing(){System.out.println("年龄为"+age+"的小学生"+name+"正在考试...");}
}
//测试
public class Test {public static void main(String[] args) {Pupil pupil = new Pupil();pupil.name = "rose";pupil.age = 19;pupil.testing();//年龄为19的小学生rose正在考试...}
}

2、扩展性和维护性提高了

当在父类中添加一个方法或者属性,而其下的所有类都可以调用这个方法或者属性

细节

1、父类中使用private 定义的变量和方法不会被继承,不能在子类中直接操作父类定义私有的变量和方法,但是可以在父类中公有的方法来获取属性和方法。

//父类中属性私有,子类不能调用
private String name;//属性私有
private void call(){}//方法私有public String showName(){return name;
}
public void showCall(){call();
}

2、子类在创建对象必须调用父类的构造器,完成父类的初始化

//父类
public Student(){System.out.println("父类构造器被调用....");
}
//子类
public Pupil(){System.out.println("子类构造器被调用....");
}
//测试
Pupil pupil = new Pupil();
输出:父类构造器被调用....子类构造器被调用....

默认在子类的构造器中有super(),无论写与不写都默认存在

3、当创建子类对象时,不管使用子类的哪个构造器,默认情况下都会调用父类的无参构造器;如果父类没有提供无参构造器,则必须在子类的构造器中用super去指向使用父类的哪一个构造器完成对父类的初始化,否则编译不会通过

4、如果希望指定去调用父类的某一个构造器,就需要显式的调用一下

super(参数列表)

注意:

  • super在使用时,必须放在构造器的第一行,构造器在执行时,先执行父类的构造器后执行子类的构造器
  • super()和this()都只能放在构造器第一行,因此这两个方法不能共同存在一个构造器中国

5、java所有类都是Object的子类,Object是所有类的父类

6、父类构造器的调用不限于直接父类,将一直往上追溯直到Object类,也就是他们的顶级父类

7、子类最多只能直接继承一个父类,java中是单继承机制

8、不能滥用继承,子类和父类之间必须满足is-a的逻辑关系

即Cat is Animal、Pupil is Student

继承本质

分析子类继承父类,创建子类对象时,内存发生了什么?

案例:

public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();}
}
class Grandpa{String name = "大头爷爷";String hobby = "旅游";
}
class Father extends Grandpa{String name = "大头爸爸";int age = 39;
}
class Son extends Father{String name = "大头儿子";
}

内存布局:

1、先加载顶级父类object,然后再加载grandpa,再加载father,最后加载son类

2、在堆存放son对象的数据,然后指向方法区的字符串常量池

3、当把堆的数据分配好后,并且指向也建立好后,0x11就会配给主方法对象引用

而创建完Son对象后,如何调用Grandpa和Father类中相同的属性

  • 首先看子类是否有该属性,如果子类有这个属性,并且可以访问(可能属性私有化),则返回子类属性的信息
  • 如果子类没有该属性,就向上查找父类有没有这个属性,如果父类有属性,并且可以访问,就返回父类属性的信息
  • 如果父类没有这个属性,继续向上找父类,直到Obejct,还是没有,就会报错

多态

当类很多,而且对对象操作操作的方法很多,不利于管理和维护,从而多态就被建立了

方法或对象具有多种形态是面向对象的第三大特征,多态是建立在封装和继承基础上的

多态的具体体现

  • 方法的多态,重写和重载就体现了多态

    • 重载

      public int sum(int n1,int n2){return n1+n2;
      }
      public int sum(int n1,int n2,int n3){reruen n1+n2+n3;
      }
      

      两个方法构成重载,通过不同的参数个数去调用sum方法,就会去调用不同的方法,对于sum方法来说就是多种状态的体现

    • 重写

      A类中方法
      public void show{System.out.println("A类方法show被调用了");
      }在B类中重写show方法
      public void show{System.out.println("B类方法show被调用了");
      }
      

      在一个不同对象中写相同方法就是重写,对于show方法来说就是多种状态的体现

  • 对象的多态

    • 一个对象的编译类型和运行类型可以不一样
    • 编译类型在定义对象时,就确定了不能改变
    • 运行类型是可以变化的
    • 编译类型看定义时=号的左边,运行类型看=号的右边
    Animal animal = new Dog();
    //animal的编译类型是Animal,而运行类型是Doganimal = new Cat();
    //animal的运行类型变成了Cat, 而编译类型仍然是animalanimal.call();//输出的是Cat的call方法
    //运行时,执行到这行时,animal的运行类型是Cat,所以是Cat的call()
    

多态可以统一管理对象操作方法

public void feed(Animal animal,Food food){System.out.println("主人"+name+"给"+animal.getName()+"吃"+food.getName  ());
}

animal编译类型是Animal,可以指向Animal子类的对象,而food编译类型是Food,可以指向Food子类的对象,当animal子类对象执行方法,不用在对方法进行重写或重载,只需要运行对象初始化成使用对象即可调用方法,不用再具体编译

细节分析

1、首先确定的是,多态是封装和继承的基础之上建立的,多态的前提是两个对象存在继承关系

2、还有就是多态的向上转型,他的本质就是父类的引用指向了子类的对象(animal指向cat)

  • 可以调用父类的所有成员,但是还是遵守访问权限
  • 不能调用子类特有的成员
  • 最终的运行结果看子类的具体实现,即调用方法从运行类型的本类开始查找方法

3、多态的向下转型

Dog dog = (Dog) animal();
子类类型 引用名 =     (子类类型)父类引用
这时dog的编译类型和运行类型都是Dog
  • 只能强转父类的引用,不能强转父类的对象
  • 要求父类的引用必须指向的是当前的目标类型的对象(dog指向dog)
  • 可以调用子类类型中所有的成员

注意:

Dog dog = (Dog) animal();
Cat cat = (Cat) animal();
//会报错

这时Animal向下转型成dog,指向了Dog对象,而下一句就是cat指向现在父类animal的引用指向Dog对象,即cat指向Dog对象,明显是不对的

面向对象三大特征(封装、继承、多态)详解相关推荐

  1. python多态的三种表现形式_python小结----面向对象的三大特征(封装,继承,多态)

    面向对象的三大特征: 封装,继承,多态 面向对象的编程思想核心:高类聚,低耦合–程序的设计模式范畴 封装 什么是封装: 在面向对象编程的思想中,对代码进行高度封装,封装又叫包装 封装就是指将数据或者函 ...

  2. 【Java编程进阶】封装继承多态详解

    推荐学习专栏:Java 编程进阶之路[从入门到精通] 文章目录 1. 封装 2. 继承 2.1 继承的语法 2.2 子类重写父类的方法 2.3 子类隐藏父类的方法 2.4 super 关键字 2.5 ...

  3. Java基础知识之封装+继承+多态详解

    前言 这篇博客是基于Java类和对象的基础之上的相关知识点.因为特别重要且语法规则较多,所以想单独总结方便之后复习. 本篇博客涉及知识点思维导图: 目录 1.封装 2.继承 3.多态 1.封装 生活中 ...

  4. java 面向对象三大特性之继承 万字详解(超详细)

    目录 前言 : 一.为什么需要继承: 二.什么是继承(Warning : 篇幅较长)? 1.继承概述: 2.子类继承父类之后达到的效果 : ①如何使用继承? ②代码演示 : 3.继承的使用场景: eg ...

  5. Python学习笔记④——类、面向对象的三大特征 [封装+继承+多态]

    ✅ Blogger Learns Python is for learning the "Deep Learning". 文章目录 一.面向对象编程的简介 二.类与对象 -- 基础 ...

  6. OC面向对象的三大特征(封装 继承 多态)习题2 复合

    复合:一个类中有一个成员变量是另外一个类的对象. 比如我现在要制作一台电脑,电脑需要CPU,显示器,鼠标和键盘等.这些东西的研发都是很复杂的过程.如果现在有成型的CPU等组件,就可以直接用这些组件攒一 ...

  7. Java面向对象三大特性(封装继承多态)解释及案例

    文章目录 包 包基本语法 命名规则 命名规范 导入包实例 访问修饰符 面向对象编程-封装 面向对象编程-继承 super关键词 super和this的比较 方法重写/覆盖 (override) 注意事 ...

  8. 三大特征 封装 继承 多态

    ''' 1.面向对象与面向过程 面向过程:核心过程二字,过程即解决问题的步骤,就是先干什么后干什么 基于该思想写程序就好比在这是一条流水线,是一种机械式的思维方式 优点:复杂的过程流程化 缺点:扩展性 ...

  9. 深入理解Java面向对象三大特性 封装 继承 多态

    1.封装 封装的定义: 首先是抽象,把事物抽象成一个类,其次才是封装,将事物拥有的属性和动作隐藏起来,只保留特定的方法与外界联系 为什么需要封装: 封装符合面向对象设计原则的第一条:单一性原则,一个类 ...

  10. c++局部对象是什么_面向对象三大特征: 封装

    今日内容 面向对象概述 类和对象的关系 面向对象内存图 private.this关键字和封装 面向对象之构造方法 面向对象三大特征 封装 继承 多态 01. 面向过程和面向对象思想概述 什么是面向过程 ...

最新文章

  1. AutoFac在项目中的应用
  2. web服务器time_wait值过高解决方案
  3. Docker学习笔记之保存和共享镜像
  4. oracle 合并重复数据_三天三夜整理出来的数据库常见的面试题,让你直接拿走...
  5. elementui表格宽度适应内容_elementui表格中的列怎么实现自适应列宽
  6. Redis(十四):Jedis
  7. C++/C--C++中substr和Java的substring对比【转载】
  8. 【资源下载】921页《用Python3带你从小白入门机器学习实战》教程手册
  9. 物联网linux_Linux的未来,Google的物联网标准等
  10. Scala-列表操作
  11. 进击的雨燕----------基本运算符
  12. iOS底层探索之Runtime(一):运行时方法的本质
  13. python备份文件
  14. Process相关函数
  15. c++程序员面试宝典
  16. 单机关系型数据库与分布式数据库的区别
  17. 如何实现批量替换文件夹名称?
  18. 工商阿里忙互殴 苏宁高调打假争做主角?
  19. Gin显示静态文件如图片,音频
  20. iamp是什么意思计算机网络,IAMP是什么意思

热门文章

  1. bert生成句子向量
  2. 激光SLAM之图优化理论
  3. 35岁的程序员:第19章,过年
  4. 数据增强 - 当数据有限时如何使用深度学习(一)
  5. GOM引擎玩家组队触发功能脚本,新开传奇创建小组时触发的教程说明
  6. 个人使用linux软件分享
  7. 痛心!一题可见余之弱鸡
  8. LOJ #2405. 「THUPC 2017」玩游戏 / Game
  9. Mini Adventure-A
  10. Servlet--基本二(请求对象,文件下载)