JAVA面向对象与内存分析

来源:互联网 发布:电脑板绘软件 编辑:程序博客网 时间:2024/06/05 04:55

前几天又重新学习了JAVA内存分析部分,温故确实可以知新,结合最近对面向对象的总结,找到二者可以连通的对比,从而把这两个结点连接起来。

面向对象

    先说说面向对象,众所周知,面向对象三大特性为:继承、封装、多态。但是再细想,这三个特性的实现还是有前后的依赖关系的,即先封装才能有继承,有了继承才能体现多态。如果你往前想一步,对,在封装前面还应该有个抽象,有了抽象,才有类,才有封装的载体,所以如果给这些特性加上顺序,应该是:

  • 抽象:面对这个世界,首先抽象、归类、汇总
  • 封装:使用类这个载体,将这组有共同特性的内容封装起来
  • 继承:有了封装后,可以在一个类的基础上继续添加内容,从而有了继承
  • 多态:有了继承和接口后,从而有了多态的实现基础
  • 更多:面向对象有了以上特性,再加上灵活的思路,从而有了延迟实现、动态加载等更多特性
    再总结一下设计模式,你会发现,基本上都是在多态的基础上进化出来的。

内存分析

    以上是从概念上分析了面向对象,接下来我们看一下他们在内存中是如何实现的,首先来看一下内存的划分图:

    

    其中:

  • stack用于存放局部变量名及其值,对象类型则为指针
  • heap用于存放对象
  • data segment用于存放静态变量和字符串常量
  • code segment用于存放代码

    抽象

    抽象,是对众多事物的归类,可以说是找出类的过程,如果要将抽象与内存关联起来,虽然有些牵强,但可以反应到类,即代码上,从而体现在code segment。

    

    封装

    封装即是将有一组有共同特性的属性和方法包装起来,它们是作为一个整体出现的,这个体现在内存中,我的理解是,以对象在堆的方式保存着,即只要在为对象分配的地址内,就属于这个整体;属于这个整体就要在这个地址段内:


    继承

    在以前的博客中也提到过,在内存中,父对象包含在子对象中,通过子对象super指针指向父对象,通过this指向自身,我们以父类为animal,子类为dog为例:

    

    我们可以理解成,继承在内存中的表现形式是子类将父类包含起来,将animal融合到dog中,封装起来(参见上面的封装),进而dog可以使用animal中的内容。

    多态

    多态的实现在内存中体现的较为复杂,但是其核心还是提前定义,延迟实现。我们仍以dog继承animal为例,让dog中的eat()覆写animal中的eat():

    

    

    一旦覆写,那么即使以animal为类型实例化的dog对象,执行eat()时,父类animal中的eat()指向了dog的eat(),从而执行dog的eat()。

    这种利用父类类型实例化,子类覆写父类的方法后,运行时,动态的再指向子类的实现,即为多态。

    实例

    我们看一个多态的很简单实例,以cat、dog继承animal为例:

public class animal{public static void main( String[ ] args ){//以父类的名义实例化animal dog=new dog( );animal cat=new cat( );//以子类自己的形式实现dog.eat( );cat.eat( );}public void eat(){System.out.println( "animal.eat" );}}class dog extends animal{@Overridepublic void eat(){System.out.println( "dog.eat" );}}class cat extends animal{@Overridepublic void eat(){System.out.println( "cat.eat" );}}

   运行结果

dog.eatcat.eat

设计模式

    看完上面的分析,再来看设计模式,其实设计模式核心就是提前定义、延迟实现,然后在此基础上灵活多变,从而实现相当经典的设计模式。

    策略模式

    我们以策略模式为例:

package muiltple;public class StrategyDemo{/** @MethodName: main * @Description: TODO * @param args */public static void main( String[ ] args ){Context ctx=new Context( new Minus( ) );ctx.count(  );Context ctx1=new Context( new Add( ) );ctx1.count(  );}public int count(int x,int y){return  x+y;}}//上下文,用于决定执行哪个策略子类算法class Context{Strategy strategy;public Context(Strategy strategy){this.strategy=strategy;}public void count(){strategy.count( );}}//策略父类class Strategy{public void count(){}}//Minus算法系类class Minus extends Strategy{@Overridepublic void count(){System.out.println( "我执行Minus中的count算法");}}//Add算法系类class Add extends Strategy{@Overridepublic void count(){System.out.println( "我执行Add中的count算法");}}

    执行结果

我执行Minus中的count算法我执行Add中的count算法

    比较策略模式和上面多态的例子,你会发现,我去,仅仅是多了一个Context这个中转类而已。

总结

   从比较基础的内容出发,多比较,再去分析上层的内容,会简单的多。


0 0
原创粉丝点击