JAVA面向对象与内存分析

    前几天又重新学习了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
	{
		@Override
		public void eat()
		{
			System.out.println( "dog.eat" );
		}
	}
	class cat extends animal
	{
		@Override
		public void eat()
		{
			System.out.println( "cat.eat" );
		}
	}

   运行结果

dog.eat
cat.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
	{
		@Override
		public void count()
		{
			System.out.println( "我执行Minus中的count算法");
		}
	}
	//Add算法系类
	class Add extends Strategy
	{
		@Override
		public void count()
		{
			System.out.println( "我执行Add中的count算法");
		}
	}

    执行结果

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

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

总结

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




  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值