1.封装

封装的定义:

首先是抽象,把事物抽象成一个类,其次才是封装,将事物拥有的属性和动作隐藏起来,只保留特定的方法与外界联系

为什么需要封装:

封装符合面向对象设计原则的第一条:单一性原则,一个类把自己该做的事情封装起来,而不是暴露给其他类去处理,当内部的逻辑发生变化时,外部调用不用因此而修改,他们只调用开放的接口,而不用去关心内部的实现

举例:

public class Human

{

private int age;

private String name;

public int getAge()

{

return age;

}

public void setAge( int age ) throws Exception

{

//封装age的检验逻辑,而不是暴露给每个调用者去处理

if( age > 120 )

{

throw new Exception( "Invalid value of age" );

}

this.age = age;

}

public String getName()

{

return name;

}

public void setName( String name )

{

this.name = name;

}

}

2. 继承

Java的类可以分为三类:

类:使用class定义,没有抽象方法

抽象类:使用abstract class定义,可以有也可以没有抽象方法

接口:使用inerface定义,只能有抽象方法

在这三个类型之间存在如下关系:

类可以extends:类、抽象类(必须实现所有抽象方法),但只能extends一个,可以implements多个接口(必须实现所有接口方法)

抽象类可以extends:类,抽象类(可全部、部分、或者完全不实现父类抽象方法),可以implements多个接口(可全部、部分、或者完全不实现接口方法)

接口只能extends一个接口

继承以后子类可以得到什么:

子类拥有父类非private的属性和方法

子类可以添加自己的方法和属性,即对父类进行扩展

子类可以重新定义父类的方法,即多态里面的覆盖,后面会详述

关于构造函数:

构造函数不能被继承,子类可以通过super()显示调用父类的构造函数

创建子类时,编译器会自动调用父类的 无参构造函数

如果父类没有定义无参构造函数,子类必须在构造函数的第一行代码使用super()显示调用

类默认拥有无参构造函数,如果定义了其他有参构造函数,则无参函数失效,所以父类没有定义无参构造函数,不是指父类没有写无参构造函数。看下面的例子,父类为Human,子类为Programmer。

public class Human

{

//定义了有参构造函数,默认无参构造函数失效

public Human(String name)

{

}

}

public class Programmer

extends Human

{

public Programmer()

{

//如不显示调用,编译器会出现如下错误

//Implicit super constructor Human() is undefined. Must explicitly invoke another constructor

super( "x" );

}

}

为什么需要继承:

代码重用是一点,最重要的还是所谓想上转型,即父类的引用变量可以指向子类对象,这是Java面向对象最重要特性多态的基础

3. 多态

在了解多态之前,首先需要知道方法的唯一性标识即什么是相同/不同的方法:

一个方法可以由:修饰符如public、static+返回值+方法名+参数+throw的异常 5部分构成

其中只有方法名和参数是唯一性标识,意即只要方法名和参数相同那他们就是相同的方法

所谓参数相同,是指参数的个数,类型,顺序一致,其中任何一项不同都是不同的方法

何谓重载:

重载是指一个类里面(包括父类的方法)存在方法名相同,但是参数不一样的方法,参数不一样可以是不同的参数个数、类型或顺序

如果仅仅是修饰符、返回值、throw的异常 不同,那这是2个相同的方法,编译都通不过,更不要说重载了

//重载的例子

public class Programmer

extends Human

{

public void coding() throws Exception

{

}

public void coding( String langType )

{

}

public String coding( String langType, String project )

{

return "";

}

}

//这不是重载,而是三个相同的方法,编译报错

public class Programmer

extends Human

{

public void coding() throws Exception

{

}

public void coding()

{

}

public String coding()

{

return "";

}

}

何谓覆盖/重写:

覆盖描述存在继承关系时子类的一种行为

子类中存在和父类相同的方法即为覆盖,何谓相同方法请牢记前面的描述,方法名和参数相同,包括参数个数、类型、顺序

public class Human

{

public void coding( String langType )

{

}

}

public class Programmer

extends Human

{

//此方法为覆盖/重写

public void coding( String langType )

{

}

//此方法为上面方法的重载

public void coding( String langType, String project )

{

}

}

覆盖/重写的规则:

子类不能覆盖父类private的方法,private对子类不可见,如果子类定义了一个和父类private方法相同的方法,实为新增方法

重写方法的修饰符一定要大于被重写方法的修饰符(public > protected > default > private)

重写抛出的异常需与父类相同或是父类异常的子类,或者重写方法干脆不写throws

重写方法的返回值必须与被重写方法一致,否则编译报错

静态方法不能被重写为非静态方法,否则编译出错

理解了上述知识点,是时候定义多态了:

多态可以说是“一个接口,多种实现”或者说是父类的引用变量可以指向子类的实例,被引用对象的类型决定调用谁的方法,但这个方法必须在父类中定义

多态可以分为两种类型:编译时多态(方法的重载)和运行时多态(继承时方法的重写),编译时多态很好理解,后述内容针对运行时多态

运行时多态依赖于继承、重写和向上转型

上例子:

class Human

{

public void showName()

{

System.out.println( "I am Human" );

}

}

//继承关系

class Doctor

extends Human

{

//方法重写

public void showName()

{

System.out.println( "I am Doctor" );

}

}

class Programmer

extends Human

{

public void showName()

{

System.out.println( "I am Programmer" );

}

}

public class Test

{

//向上转型

public Human humanFactory( String humanType )

{

if( "doctor".equals( humanType ) )

{

return new Doctor();

}

if( "programmer".equals( humanType ) )

{

return new Programmer();

}

return new Human();

}

public static void main( String args[] )

{

Test test = new Test();

Human human = test.humanFactory( "doctor" );

human.showName();//Output:I am Doctor

human = test.humanFactory( "programmer" );

human.showName();//Output:I am Programmer

//一个接口的方法,表现出不同的形态,意即为多态也

}

}

向上转型的缺憾:

只能调用父类中定义的属性和方法,对于子类中的方法和属性它就望尘莫及了,必须强转成子类类型

总结概括:

当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)

稍微复杂的例子:

class Human {

public void fun1() {

System.out.println("Human fun1");

fun2();

}

public void fun2() {

System.out.println("Human fun2");

}

}

class Programmer extends Human {

public void fun1(String name) {

System.out.println("Programmer's fun1");

}

public void fun2() {

System.out.println("Programmer's fun2");

}

}

public class Test {

public static void main(String[] args) {

Human human = new Programmer();

human.fun1();

}

/*

* Output:

* Human fun1

* Programmer's fun2

*/

}

Programmer中的fun1(String name) 和Human中的fun1(),只是方法名相同但参数不一样,所以是重载关系

Programmer中的fun2()和Human中的fun2()是相同的方法,即Programmer重写了Human的fun2()方法

把Programmer的对象向上转型赋值个Human后,human.fun1()会调用父类中的fun1()方法,子类的fun1(String name)是不同的方法

在human的fun1()中又调用了fun2()方法,该方法在Programmer中被重写,实际调用的是被引用变量Programmer中的fun2()方法

package test;

class A {

public void func() {

System.out.println("func in A");

}

}

class B extends A {

public void func() {

System.out.println("func in B");

}

}

class C extends B {

public void func() {

System.out.println("func in B");

}

}

public class Bar {

public void test(A a) {

a.func();

System.out.println("test A in Bar");

}

public void test(C c) {

c.func();

System.out.println("test C in Bar");

}

public static void main(String[] args) {

Bar bar = new Bar();

A a = new A();

B b = new B();

C c = new C();

bar.test(a);

bar.test(b);

bar.test(c);

/*

func in A

test A in Bar

func in B

test A in Bar

func in B

test C in Bar

*/

}

}

java封装继承多态的理解_深入理解Java面向对象三大特性 封装 继承 多态相关推荐

  1. Python OOP:面向对象三大特性(封装、继承、多态)、类属性和实例属性、类方法@classmethod、静态方法@staticmethod、函数和类callable、__call__

    一.面向对象三大特性 二.多态 定义:多态是⼀种使⽤对象的⽅式,⼦类重写⽗类⽅法,调⽤不同⼦类对象的相同⽗类⽅法,可以产⽣不同的执⾏结果. 一个父类,可以继承给多个子类,每个不同的子类可以创建多个对象 ...

  2. 大数据必学Java基础(四十):面向对象三大特性之一继承(Inheritance)

    文章目录 面向对象三大特性之一继承(Inheritance) 一.列举案例说明 1.类是对对象的抽象

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

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

  4. C++面向对象三大特性——封装与信息隐蔽

    4.1 封装(实现手段--class) 有意义的事物都可以抽象.在抽象类的时候不要想着代码是怎么实现,而是用自然语言去分析逻辑即可!否则极易出错. 4.1.1 封装的意义 封装是C++面向对象三大特性 ...

  5. Java面向对象三大特性(封装、继承、多态)

    文章目录 前言 一.封装 1. 封装的概念 2. private实现封装 3. getter和setter方法 4.封装的好处 二.继承 1. 继承的概念 2. extends实现继承 3. supe ...

  6. Java面向对象三大特性之继承多态的预习笔记,are you ready? 面对疾风吧!

    文章目录 继承(extends) super关键字 方法重写 instanceof关键字 abstract关键字 接口(interface) 多态 继承(extends) AextendsB A继承了 ...

  7. C++——面向对象三大特性之继承

    文章目录 继承概念 继承的定义 继承的语法格式 继承方式 继承方式的汇总 赋值兼容规则 基类对象和派生类对象的赋值转换 继承中的作用域 派生类的默认成员函数 继承与友元 继承与静态成员 菱形继承 虚继 ...

  8. 面向对象三大特性之一:多态(C++)

    目录 多态的定义及实现 抽象类 多态的原理 单继承和多继承关系的虚函数表 多态的定义及实现 1.什么是多态? 当不同的对象去完成某个行为时,会产生出不同的结果.多态是:不同继承关系的类对象去调用同一函 ...

  9. 面向对象三大特性(继承)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.今日回顾 1.<高等数学>:一节网课 2.阅读:<费马大定理>300页 3.英语:120个 ...

  10. 面向对象三大特性之继承

    2019独角兽企业重金招聘Python工程师标准>>> 1:继承,顾名思义就是子代继承父辈的一些东西,在程序中也就是子类继承父类的属性和方法. 1 #Author : Kelvin2 ...

最新文章

  1. 如何使用 UserAccountControl 标志操纵用户帐户属性
  2. python课程内容-Python自学难吗?有哪些课程内容?
  3. 参考滴滴左右对齐自适应
  4. 迁移学习与微调的区别
  5. mongodb查询值不为空_MongoDB使用规范(上)
  6. 可穿戴设备创业:现在和未来
  7. 8s yaml 配置生成_cfg4py:一个严肃的Python配置模块应有的风格-层级式、部署环境自适应、自动补全...
  8. HTML5学习笔记四: 列表, 块和布局
  9. 弹跳机器人 桌游_MIT机器人轻松搞定桌游叠叠乐:你能玩过它算我输 |《科学》子刊...
  10. linux malloc free 内存碎片_内存申请malloc/new与内存释放free/delete的区别
  11. socket编程(一)
  12. 【七】zuul路由网关
  13. 二、C++反作弊对抗实战 (进阶篇 —— 10.利用硬件断点 + 结构化异常VEH HOOK与对抗方法)
  14. 8cm等于多少像素_一寸照片像素是多少
  15. Presupposition
  16. KOReader开源PDF支持多平台
  17. 量化免费行情源最强对比分析--看这篇就够了
  18. 周报告工作总结计算机,计算机实训工作总结报告
  19. 学区摇号软件设计_小升初家长必看!2018年最全升学信息及小摇号汇总分析。...
  20. mysql bulk update_Bulk Upsert for MySQL PostgreSQL

热门文章

  1. grads 相关系数_气象绘图软件GrADS高级使用技巧
  2. 春天来了,北京周边哪里去~
  3. 菜鸟java基础--1
  4. JDK动态代理原理解析
  5. Tomcat8的下载、安装、配置
  6. qqkey获取原理_【逆向】QQkey盗号木马原理分析
  7. Javascript 设置Cookie
  8. 评价法(二):模糊综合评价的步骤和方法
  9. 分享几个微信小程序的视频教程
  10. 数字电路基础知识——数字IC中的进制问题(原码,反码,补码以及各进制的转换)