Java多态的学习

首先,我要说明的是,继承、封装、多态并不是针对JAVA,c#或者其他某种语言产生的,它是面向对象思想下产生的一个概念。

让我自己说的话,我只能用三句话来描述(不知道对不对,请高手指点):

  * 继承:使得子类继承父类的属性和方法,也可以使用父类的功能。

  * 封装:将具体实现隐藏,只留给用户使用的接口。

  * 多态:相似类型在使用同一基类方法时,可以表现出与基类不同的行为。

一直记不住这些概念,百度了下,放在这供参考:

1、继承(inheritance)     继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。

继承是为了重用父类代码,同时为实现多态性作准备。
  2、封装(encapsulation)     类使得数据和对数据的操作集成在一起,从而对使用该类的其他人来说,可以不管它的实现方法,而只管用它的功能,从而实现所谓的信息隐藏。  封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据。

3、多态(polymorphism)

方法的重写、重载与动态连接构成多态性。Java之所以引入多态的概念,原因之一是它在类的继承问题上和C++不同,后者允许多继承,这确实给其带来的非常强大的功能,但是复杂的继承关系也给C++开发者带来了更大的麻烦,为了规避风险,Java只允许单继承,派生类与基类间有IS-A的关系(即“猫”is a “动物”)。这样做虽然保证了继承关系的简单明了,但是势必在功能上有很大的限制,所以,Java引入了多态性的概念以弥补这点的不足,此外,抽象类和接口也是解决单继承规定限制的重要手段。同时,多态也是面向对象编程的精髓所在。     多态又分为设计时多态和运行时多态,例如重载又被称为设计时多态,而对于覆盖或继承的方法,JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。总而言之,面向对象的设计的典型特点就是继承,封装和多态,这些特点也是面向对象之所以能如此盛行的关键所在。

对于多态,可以总结它为:

    一、使用父类类型的引用指向子类的对象;该引用只能调用父类中定义的方法和变量;

    二、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)

    三、变量不能被重写(覆盖),重写的概念只针对方法。

对多态的理解:

个人觉得多态是最为抽象的一个概念,那就用实例来解释了。

1. public, protected的方法具有多态性,但是如果某个方法是静态的,就不具有多态性,因为静态方法是与类而非单个对象相关联的。

package com.wx.test;

public class Base {

    public void publicMethod() {
        System.out.println("Base public Method");
    }

    protected void protectedMethod() {
        System.out.println("Base protected Method");
    }

    public static void publicStaticMethod() {
        System.out.println("Base protected Method");
    }
}

public class Sub1 extends Base {

    public void publicMethod() {
        System.out.println("Sub1 public Method");
    }

    protected void protectedMethod() {
        System.out.println("Sub1 protected Method");
    }

    public static void publicStaticMethod() {
        System.out.println("Sub1 protected Method");
    }
}

public class Sub2 extends Base {

    public void publicMethod() {
        System.out.println("Sub2 public Method");
    }

    protected void protectedMethod() {
        System.out.println("Sub2 protected Method");
    }

    public static void publicStaticMethod() {
        System.out.println("Sub2 protected Method");
    }
}

public class Test {
    public static void main(String[] args) {
        Base base1 = new Sub1();
        Base base2 = new Sub2();
        base1.publicMethod();
        base2.publicMethod();
        base1.protectedMethod();
        base2.protectedMethod();
        base1.publicStaticMethod();
        base2.publicStaticMethod();
    }
}

运行结果如下:

Sub1 public Method
Sub2 public Method
Sub1 protected Method
Sub2 protected Method
Base protected Method
Base protected Method

  从以上结果可以看到,将子类对象转换成父类对象,对于public和protected方法调用时,是调用了实际创建的子类方法。问题就在于编译器只有一个父类对象,它无法知道调用哪个方法才对。这个问题解决办法就是后期绑定,就是编译器确实不知道调用哪个方法,运行时才根据对象类型进行绑定,从而调用子类方法。也就是编译器一直不知道对象类型,方法调用机制可以知道类型信息,从而找到正确的方法体。

2.“覆盖”私有方法

package com.wx.test;

public class Super {

    private void function()
    {
        System.out.println("Super private Method");
    }
    public static void main(String[] args) {
        Super sup = new Sub();
        sup.function();
    }

}

public class Sub extends Super{
    public void function()
    {
        System.out.println("Sub public Method");
    }

}

运行结果如下:

Super private Method

我们期望输出Sub public Method,但是由于private方法被自动认为是final方法而且对于子类是不可见的,因此Sub中的function()是一个新的方法。所以私有方法是不能被覆盖的。

  3. 属性不可以是多态的

package com.wx.test;

public class Super {
    public int field = 0;
    public int getField() { return field; }
}

public class Sub extends Super{
    public int field = 1;
    public int getField() { return field; }

}

public class Test {
    public static void main(String[] args) {
        Super sup = new Sub();
        Sub sub  = new Sub();
        System.out.println("sup.field = "+ sup.field +"," + "sup.getField() = " + sup.getField());
        System.out.println("sub.field = "+ sub.field +"," + "sub.getField() = " + sub.getField());
    }

}

运行结果如下:

sup.field = 0,sup.getField() = 1
sub.field = 1,sub.getField() = 1

  不过在实践中这种情况一般不会发生,一是属性会被定义为private,因此不能直接访问,二是子类不会定义和基类相同名字的属性,这种做法容易混淆。

时间: 2024-10-07 05:16:44

Java多态的学习的相关文章

黑马程序员-Java面向对象编程学习总结

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- Java面向对象编程学习总结: 重要知识点总结如下: 1,抽象,封装,继承,多态是面向对象程序设计中得四个特点. 2,面向对象得软件开发大体分为:面向对象的分析,面向对象的设计,面向对象的实现. 可概括为如下过程:分析用户需求,从问题中抽

Java 多态——与C++的比较

学习了Java和C++之后,由于长期不使用C++,而java的基础知识掌握不牢,现在已经搞不清java多态了.现在先来谈谈java多态,稍后有时间再更新C++的多态,并进行比较~ 一. Java的多态 首先什么是Java的多态? 多态是同一个行为具有多个不同表现形式或形态的能力.多态就是同一个接口,使用不同的实例而执行不同操作. 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法. 多态的作用:消除类型之间的耦

java多线程入门学习(一)

java多线程入门学习(一) 一.java多线程之前 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.     线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小.     线程和进程一样分为五个阶段:创建.就绪.运行.阻塞.终止.     多进程是指操作系统能同时运行多个任务(程序).     多线程是指在同一程序中有多个顺序流在执行. 在java中要想实现多线程,有两种手段,一种是继承T

Java Web入门学习路线图的规划

Java作为学习编程开发入门语言,可能对于许多新手来说可能有点摸不着北,做位一名有几年开发经验的老鸟,希望给一些新人分享经验,当然其他老鸟如果有什么意见可以指出,我也会努力纠正. 本人工作是有关Java Web 开发,所以我会以Java Web标准开发去做一个标准,当然Java 能做的事情很多,包括Android,Java Me等,后期只要我们努力可以学习更多,更深的我也说不了,我现在只谈谈怎么去入门,至于登堂入室,大家有了套路以后,都能够达到.我写这个初衷,是因为我本来是一名非计算机专业的学生

20165210 Java第四周学习总结

20165210 Java第四周学习总结 教材学习内容 第五章学习总结 子类与父类: 子类: class 子类名 extends 父类名 { ... } 类的树形结构 子类的继承性: 子类和父类在同一包中的继承性 子类和父类不在同一包中的继承性 继承关系的UML图 protected的进一步说明 子类与对象 子类对象的特点 关于instanceof运算符 成员变量的隐藏的方法重写 成员变量的隐藏: 子类对象以及子类自己定义的方法操作与父类同名的成员变量是指子类重新声明的这个成员变量. 子类对象仍

Java多态之向下转型

目录 Java多态之向下转型 强制类型转换 instanceof Java多态之向下转型 往期回顾:我们学习了向上转型和动态绑定的概念,可以知道在继承关系中,将一个子类对象赋值给父类的引用变量,调用父类的方法,在实际运行时,就可以根据子类中重写的方法执行不同的操作.其中有一个弊端,就是在向上转型的过程中,其实丢失了一部分子类特有的功能,毕竟它只允许调用父类中的方法.那么,如何在这时调用子类中的方法呢,这时就需要与向上转型相对应的方法,就是所谓的:向下转型. 向上转型是自动就能完成的,向下转型则需

java/android 设计模式学习笔记(14)---外观模式

这篇博客来介绍外观模式(Facade Pattern),外观模式也称为门面模式,它在开发过程中运用频率非常高,尤其是第三方 SDK 基本很大概率都会使用外观模式.通过一个外观类使得整个子系统只有一个统一的高层的接口,这样能够降低用户的使用成本,也对用户屏蔽了很多实现细节.当然,在我们的开发过程中,外观模式也是我们封装 API 的常用手段,例如网络模块.ImageLoader 模块等.其实我们在开发过程中可能已经使用过很多次外观模式,只是没有从理论层面去了解它. 转载请注明出处:http://bl

java/android 设计模式学习笔记(10)---建造者模式

这篇博客我们来介绍一下建造者模式(Builder Pattern),建造者模式又被称为生成器模式,是创造性模式之一,与工厂方法模式和抽象工厂模式不同,后两者的目的是为了实现多态性,而 Builder 模式的目的则是为了将对象的构建与展示分离.Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程.一个复杂的对象有大量的组成部分,比如汽车它有车轮.方向盘.发动机.以及各种各样的小零件,要将这些部件装配成一辆汽车,这个装配过

Java程序猿学习当中各个阶段的建议

回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议 引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的对话都给记下来.LZ自己当初面试完以后,除了记住一些聊过的知识点以外,具体的内容基本上忘得一干二净,所以写这篇文章其实是很有难度的. 但是,最近问LZ的人实在是太多了,为了避免重复回答,给自己省点力气,干脆就在这里统一回复了. 其实之前LZ写过一篇文章,但是那篇文章更多的是在讨论“面试前该不该刷题”这个