Java的继承、封装与多态

基本概念

  • 面向对象OO(Object Oriented):把数据及对数据的操作方法放在一起,作为一个相互依存的整体,即对象。
  • 对同类对象抽象出共性,即类。

    比如人就是一个类,所有的人都有一些共同的属性,比如身高体重肺活量,还有一些特定的操作,即方法,比如吃饭,思考。但是人只是一个抽象的概念,所有具备人这个群体的属性和方法的对象都叫人,我们只能说张三这个实例化的人身高是多少,体重是多少,而不能说人这个类身高是多少。
  • OOP面向对象编程:指软件开发的过程中,通过面向对象的思想进行表达和实现。
  • 重构:指对程序做出一定的改变。

面向对象的特征:

封装,继承与多态。

封装

有时称为数据隐藏

将数据和和对数据的操作隐藏在一个类中,即隐藏对象的属性和实现细节,仅对外公开接口。

使用者不需要知道类的具体实现,只要知道怎么调用就可以了。

比如:

所有类的成员变量一般设置为private,如果需要访问和修改,通过getter和setter方法,优点:

1.可以改变内部实现,除了该类的方法外,不会影响其他代码。

private String firstName;
private String lastName;
public String getName(){
return firstName + "" + lastName;
}

2.setter方法可以执行错误检查,比如检查数据是否合乎规范,输入的age是否小于0,直接对域操作则没这种优势

3.可细微划分访问控制:可以只设置域访问器getter,不设置域修改器setter,让用户只能读取,而不能修改。而public既可以读取,也可以修改,可能造成数据不安全。

继承

是一种类的层次模型,从现有的类中通过extends关键字派生新类,现有的类称为父类,新类称为子类。

子类可以从它的父类那里继承方法和实例变量,并且可以重写父类的方法和增加新的方法。一般将通用的方法放到超类中,具有特殊用途的方法放到子类中。

特点:

  1. 不能多重继承。
  2. 只能继承非私有的成员变量和方法
  3. 当子类成员变量与父类成员变量重名时,子类覆盖父类。
  4. 定义为final的类不可继承,定义为final的方法不可以被重写。

多态

  • 指允许不同类的对象对同一消息(即同一个方法的调用)做出响应。即同一个方法的调用,可以根据调用这个方法的对象的不同而实现不同的功能。
  • 在Java核心技术第5章中定义:

    实现多态的技术称为:动态绑定(dynamic binding),是指在运行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
  • 多态的作用:降低类型之间的耦合关系

    把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

例子

  • 比如:

    如果我们定义
Animal animal = new Cat();   //表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象

或者

Cat cat = new Cat();

如果我要改为子类Dog类,那么前者只需要修改一行代码,不需要改实例名,后者要大量改动。

Animal animal = new Dog();
  • 再比如:

    你可以设计一个接口:DataBaseDao

    然后,每个不同的数据库,你可以编写接口的实现类,比如:SQLServerDao, MySqlDao, DB2Dao等等

当用户使用你框架的时候,他就可以用多态,实现自己的数据库连接功能:

DaoBaseDao dao = new SQLServerDao(); //针对SQLServer的接口实现,这里dao就是多态

dao.connect();

  • 再比如:

    现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

但注意:父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;比如子类中增加的方法,父类引用无法调用。

多态存在的三个必要条件

一、要有继承;

二、要有重写;

三、父类引用指向子类对象。

多态的好处:

1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。

2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。

3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。

4.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

Java中多态的实现方式

  • 方法的重载(overload):重载是指同一个类中有多个同名的方法,但这些方法有不同的参数,因此在编译期就可以确定到底调用哪个方法,它是一种编译时多态。即一个类中的方法多态性。
  • 方法的覆盖(即重写)(override):子类可以覆盖父类的方法,即同样的方法会在子类和父类中有不同的表现形式。在Java语言中,父类引用可以指向父类对象或者子类对象,接口引用可以指向其实现类的实例对象。 而程序调用的方法在运行期才动态绑定(绑定指的是将一个方法调用和一个方法主体连接到一起),即:在运行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。(注意此时父类引用只是指向子类对象,真正运行的还是子类对象,即优先从实际运行的对象的方法表中找对应的方法签名(方法名+参数列表称为方法签名),如果找不到,才回到相应的父类方法表中找调用方法的方法签名),由于运行时才能确定调用哪个方法,因此称方法覆盖的多态为运行时多态

在《深入理解Java虚拟机》的P248页,

对方法的重载称为:静态分派(根据静态类型)

package org.fenixsoft.polymorphic;

/**
* 方法静态分派演示
* @author zzm
*/
public class StaticDispatch { static abstract class Human {
} static class Man extends Human {
} static class Woman extends Human {
} public void sayHello(Human guy) {
System.out.println("hello,guy!");
} public void sayHello(Man guy) {
System.out.println("hello,gentleman!");
} public void sayHello(Woman guy) {
System.out.println("hello,lady!");
} public static void main(String[] args) {
Human man = new Man();
Human woman = new Woman();
StaticDispatch sr = new StaticDispatch();
sr.sayHello(man);
sr.sayHello(woman);
}
}

运行结果:

hello,guy!
hello,guy!

注意这里的静态类型指static类型,但其实不是static类型结果也一样,只不过将内部类写为static的可以实现和外部类相同的调用方式,比如:

public class StaticDispatch {

	abstract class Human {
} class Man extends Human {
} class Woman extends Human {
} public void sayHello(Human guy) {
System.out.println("hello,guy!");
} public void sayHello(Man guy) {
System.out.println("hello,gentleman!");
} public void sayHello(Woman guy) {
System.out.println("hello,lady!");
} public static void main(String[] args) {
StaticDispatch staticDispatch = new StaticDispatch();
Human man = staticDispatch.new Man();
Human woman = staticDispatch.new Woman();
StaticDispatch sr = new StaticDispatch();
sr.sayHello(man);
sr.sayHello(woman);
}
}

代码中刻意地定义了两个静态类型相同但实际类型不同的变量,但虚拟机(准确地说是编译器)在重载时是通过参数的静态类型而不是实际类型作为判定依据的。并且静态类型是编译期可知的,因此,在编译阶段,Javac编译器会根据参数的静态类型决定使用哪个重载版本,所以选择了sayHello(Human)作为调用目标,并把这个方法的符号引用写到main()方法里的两条invokevirtual指令的参数中。

对方法的覆盖称为:动态分派(根据实际类型)

例子:

class Base {
public int i = 1; public Base() {
g();
} public void f() {
System.out.println("Base f");
} public void g() {
System.out.println("Base g");
}
} public class Derived extends Base {
public int i = 2; public void f() {
System.out.println("Derived f");
} public void g() {
System.out.println("Derived g");
} public static void main(String args[]) {
Base b = new Derived();
b.f();
System.out.println(b.i);
}
}

输出:

Derived g
Derived f
1

上面的例子说明了:只有类中的方法才有多态的概念,类中成员变量没有多态的概念。类中成员变量的值取决于所定义变量的类型,这是在编译期间确定的。

面向接口编程

参考:http://www.cnblogs.com/leoo2sk/archive/2008/04/10/1146447.html

面向接口编程和面向对象编程是什么关系

首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分。或者说,它是面向对象编程体系中的思想精髓之一。

接口的本质

  • 接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是……则必须能……”的理念。
  • 接口是在一定粒度视图上同类事物的抽象表示。比如我们说我和猴子不属于一类,分别继承Person接口和Monkey接口,但对动物学家,我们却继承同一接口:Animal接口。

面向接口编程的本质

在系统分析和架构中,分清层次和依赖关系,每个层次不是直接向其上层提供服务(即不是直接实例化在上层中),而是通过定义一组接口,仅向上层暴露其接口功能,上层对于下层仅仅是接口依赖,而不依赖具体类。

好处:

  1. 对系统灵活性大有好处。当下层需要改变时,只要接口及接口功能不变,则上层不用做任何修改。甚至可以在不改动上层代码时将下层整个替换掉。
  2. 不同部件或层次的开发人员可以并行开工,就像造硬盘的不用等造CPU的,也不用等造显示器的,只要接口一致,设计合理,完全可以并行进行开发,从而提高效率。

抽象类与接口

如果单从具体代码来看,对这两个概念很容易模糊,甚至觉得接口就是多余的,因为单从具体功能来看,除多重继承外(C#,Java中),抽象类似乎完全能取代接口。

区别

  • 使用动机。使用抽象类是为了代码的复用(可以理解为代码和表示的共享机制),而使用接口的动机是为了实现多态性。
  • 抽象类和它的子类之间应该是一般和具体的关系,而接口仅仅是它的子类应该实现的一组规则。

Java的继承、封装与多态的更多相关文章

  1. [Objective-C] 004_继承封装与多态

    继承 面向对象编程 (OOP) 语言的一个主要功能就是"继承".继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展.通过继承创建的 ...

  2. java类的封装 继承 多态

    1.猜数字小游戏 package cn.jiemoxiaodi_02; import java.util.Scanner; /** * 猜数字小游戏 * * @author huli * */ pub ...

  3. 九、Java基础---------面向对象封装、继承、多态

    封装 1.1 基本概念  封装(encapsulation)是面向对象三大特征之一,它是指将对象的状态信心隐藏在对象的内部,不允许外部直接进行访问,而是通过该类提供的方法来实现对内部信息的操作和访问. ...

  4. java类的封装、继承、多态

    一.封装(encapsulation) 封装性就是把类(对象)的属性和行为结合成一个独立的相同单位,并尽可能隐蔽类(对象)的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系.封装的特 ...

  5. Java三大特性(封装,继承,多态)

    Java中有三大特性,分别是封装继承多态,其理念十分抽象,并且是层层深入式的. 一.封装 概念:封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据 ...

  6. 第32节:Java中-构造函数,静态方法,继承,封装,多态,包

    构造函数实例 class Cat{ // 设置私有的属性 name private String name; // 设置name的方法 public void setName(String Name) ...

  7. 【Java基本功】一文了解Java中继承、封装、多态的细节

    本节主要介绍Java面向对象三大特性:继承 封装 多态,以及其中的原理. 本文会结合虚拟机对引用和对象的不同处理来介绍三大特性的原理. 继承 Java中的继承只能单继承,但是可以通过内部类继承其他类来 ...

  8. Java中的继承、封装、多态的理解

    Java中的继承.封装.多态 继承的理解: 1.继承是面向对象的三大特征之一,也是实现代码复用的重要手段.Java的继承具有单继承的特点,每个子类只有一个直接父类. 2.Java的继承通过extend ...

  9. 浅析Java三大特性封装、继承、多态,及作业分析

    前言 本次博客衔接上次博客,作为这一阶段Java学习的分析.上一篇博客着重介绍了Java的OO编程思维,面向对象与面向过程的区别.本篇博客重心在Java的三大技术特性,附带作业分析. Java三大特性 ...

随机推荐

  1. linux c函数指针的应用

    头文件:1.h #include<stdio.h> int nul_func(); int test1(int a,int b); int test2(int a,int b,int c) ...

  2. dd命令

    前言 dd命令文件处理 dd命令用于复制文件并对原文件的内容进行转换和格式化处理.dd命令功能很强大的,对于一些比较底层的问题,使用dd命令往往可以得到出人意料的效果. dd命令 转换拷贝一个文件,特 ...

  3. Ring3层 UNICODE_STRING

    今天写驱动用到UNICODE_STRING,就在Ring3层抠了一些源代码,学习一下,不多说了上代码了 #pragma once #include <windows.h> #include ...

  4. Mybatis第四篇【多表连接】

    Mybatis多表连接 我们在学习Hibernate的时候,如果表涉及到两张的话,那么我们是在映射文件中使用<set>..<many-to-one>等标签将其的映射属性关联起来 ...

  5. 对比requirejs更好的理解seajs

    seajs遵循CMD规范,requirejs遵循AMD规范.AMD规范是预加载,CMD规范是赖加载. 下文举例假设有文件 b.js, c.js如下 //b.js define(function(req ...

  6. android动画的实现过程

    先上自己的测试代码,有参考apidemo中的AnimationDrawable中的方法 public class AnimateActivity extends Activity { @Overrid ...

  7. 【 js 基础 】关于this

    this 关键字是 Javascript 中很特别的一个关键字,被自动定义在所有函数的作用域中.this提供了一种更优雅的方式隐式"传递"一个对象的引用.今天就来说说 this 的 ...

  8. Android Framework 初探

    最近工作任务不忙,学习一下Android Framework方面的知识. 一.介绍,是什么 Android的Framework是直接应用之下的一层,叫做应用程序框架层.这一层是核心应用程序所使用的AP ...

  9. Spring 具名参数NamedParameterJdbcTemplate

    具名参数: 具名参数:SQL 按名称(以冒号开头)而不是按位置进行指定. 具名参数更易于维护, 也提升了可读性. 具名参数由框架类在运行时用占位符取代 我们之前一直是用JDBCTemplate  进行 ...

  10. Python数据分析(二): Numpy技巧 (4/4)

    numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性.   第一部分: ht ...