首页 > 代码库 > JAVA 的面向对象设计的特点-书后感-01-21天学通JAVA-深入分析

JAVA 的面向对象设计的特点-书后感-01-21天学通JAVA-深入分析

</pre>JAVA 作为面向对象的一种语言究竟有哪些特点。本文尝试列举最基本的一些:从<21天学通JAVA>中摘来一些概念,并且做了一定的深挖理解。<p></p><p>本章尝试重编译顺序角度理解JAVA继承的覆盖,重写,重载的不同。可能有不对的地方,请指出。</p><p></p><p><table border="1" width="2000" cellspacing="1" cellpadding="1"><tbody></tbody></table></p><p>1 控制逻辑:</p><p>1.1 包的概念,JAVA提供包的概念,更加方便类的管理。</p><p>1.2 Final概念,final其实是对初始化的成员变量,局部变量,以及方法的一种管理和防止出错的机制。</p><p>final的方法可以继承,但是,不能重写</p><p>1.3 static概念:(理解static,我在后面有一段描述,就是在是不是编译涵括的概念)</p><p>在变量的作用域考虑时候,static的作用是对变量的作用域做了扩大化的变更,</p><p>static修饰的成员变量是属于类的(其实就是作用域是类的)不会因为新创立了一个新的对象而改变。</p><p>拓展看,java的类操作要考虑变量和类,对象的作用域,比如,静态变量作用域是依赖于类,不是对象,那么依赖于对象的方法(比如this)对静态变量的操作将导致错误。</p><p>除非,这个对象的方法已经是确认的,或者说,从java角度说,以及开辟了他自己的存在的代码空间:</p><p>也就是说,静态成员变量是可以通过<strong>非静态</strong>的方式来访问。</p><p></p><pre code_snippet_id="540606" snippet_file_name="blog_20141203_2_9778037" name="code" class="java">//bike类描述的是一个自行车
class bike
{
	//申明一个String类型的变量color
	String color = "黄色";
	
	//申明一个方法
	public final void getMes()
	{
		System.out.println("父类的成员变量color : " + color);
	}
}

//test类描述的是final修饰的成员变量
public class test9 extends bike
{
	//申明一个String类型的变量color
	String color = "绿色";
	
	//Java程序的主入口函数
	public static void main(String[] args)
	{
		//创建test类的对象实例
		test9 t = new test9();

		//调用方法打印结果
		t.getMes();
	}
}



同理,如果是一个静态方法,比如:

public static  void main (string [] args) 

{

system.out.printlin(color); // 同理这个color变量如果不是静态变量,那么也是错误的。

}


2 继承:

JAVA的继承有他的特点,首先:是单继承,也就是一个子类的父类只有一个。 其次,是多层次继承。

2.1 default: in JAVA:

JAVA的Default和public的不同在于,是否支持同一个包。

2.2 private 

JAVA的private很好的封装了你想封装的关键技术,下面的例子说明了这个封装的一个实例:


class door
{
	private String color;  //为定义为private类型
	
	//door类的构造器
	public door ()
	{
		this.color = "父类里的private类型成员变量";
	}
	
	private void openDoor() // 由于定义为private的方法,所以是无法在继承类里面使用的
	{
		System.out.println("此方法为private方法!");
	}
	
	public void openDoors() // 通过再封装的接口,可以把以及private的方法,重写后,改为public使用,从而可以被继承类所见。
	{
		openDoor ();
	}
}

//wood_Door继承与door
public class wood_Door extends door
{
	String color;<span style="white-space:pre">	</span>// 这里尝试了一个同名的成员变量

	//wood_Door类的构造器
	public wood_Door()
	{
		this.color = "是本类里的成员变量"; // 如果去掉本类中color的定义,那么此处将报错,原因是父类的成员变量是私有的
	}

	public static void main(String[] args)
	{
		wood_Door wd = new wood_Door ();
		//访问的是父类的成员变量和方法
		wd. openDoors (); // 这里访问的是又公开的方法,如果在父类中不通过新的public方法重新封装那个private接口,这里会报错<span style="white-space:pre">	</span>
		//访问的是本类的成员变量
		System.out.println(wd.color);
	}
}
运行结果如下:
此方法为private方法!
是本类里的成员变量




2.3 protected:

protected主要是指不同包和同包的范畴,以及由此影响到的成员变量和方法的作用域。v 

2.4 override and overload

override 就是类的方法的接口是完全一致的,但是,方法的具体实现不同。

overload 是方法的名称相同,但是,方法的参数列表不同。

2.5 static method

【hsy75】案,有关静态方法的理解,其实要深入到,编译上去。如果理解了编译的步骤,那么理解static的限定都比较好理解。

static就是申明在编译的时候就决定开辟的区域,我可以理解为某个段的代码区域,既然是编译时候已经加入了,那么,很好,所有的

后面的对象实例化(其实应该是在内存的堆上开辟了一块区域)显然是无法实现原有的静态方法的简单继承的。


静态方法可以被继承,但是不可以被重写

【hsy75】上句是援引书的小结,其实,有时候觉得写书的人自己是不是也是比较混沌,总提出那些奇怪的概念对比,感觉有些概念更不八杆子打不到一起。

静态方法当然是可以被继承的,静态方法无非是编译的时候被加入的,一块代码段的代码当然可以被实例化到堆上,至于能不能重写,这又什么联系呢。

因为重写就是override,就是和所继承的父类方法具有相同的名称但是有不同的具体行为。重写是子类针对父类的概念,

//把上个例子加以修改
//door类所描述的是一个门
class door
{
	
}

//wood_Door类所描述的是一个木门
class wood_Door extends door
{
	
}

class math
{
	//getMes()方法被修饰为了static public类型,请注意
	static public door getMes()
	{
		return new door();
	}
}

public class son4 extends math
{
//getMes()方法被修饰为了static public类型,请注意
	static public wood_Door getMes()
	{	
		return new wood_Door();
	}
	
	public static void main(String args[])
	{
		//创建了一个Son类的对象实例,对象引用的名称m
		math m = new son4(); // hsy75 案,此处如果改为 son m = new son();这是另外一个结果
		//打印并显示结果
		System.out.println(m.getMes());
	}
}

【hsy75】案,下面的例子是我改写的书本的例子,作为这几个概念的验证补充
//math类,描述的是一个数学类,用于数学计算
class  math
{
	//重载方法add,参数列表为int型的
	public int add(int i, int j)
	{
		return i + j;
	}
	
	//重载方法add,参数列表为float型的
	public float add(float i, float j)
	{
		return i + j;
	}
	
	// 静态方法不能重写的例子
	static public int sub(int i, int j)
	{
		return i - j;
	}
	
	// 静态方法不能重写的例子2
	static public int mux(int i, int j)
	{
		return i * j;
	}
	
	// 静态方法不能重写的例子3
	public int div(int i, int j)
	{
		return i / j;
	}
	
}	

public class chapter8_math extends math
{
		public int add(int i, int j)
		{
			return i;
		}
			
		static public int sub(int i, int j)
		{
			return j;
		}
		
		// 静态方法不能重写的例子2 【案0】
		/* 这样些编译报错 public int mux(int i, int j)
		{
			return i * j;
		}
		*/

		// 静态方法不能重写的例子3 【案0】
		/* 这样些编译报错 static public int div(int i, int j)
		{
			return i / j;
		}*/

		
		public static void main (String args[])
		{
<span style="white-space:pre">			</span>// 【案1】
			chapter8_math m = new chapter8_math();				//创建了一个对象实例math的子类chapter8_math的实例,它的对象引用为m
			System.out.println(m.add(1.0f, 2.3f));		//执行重载方法,根据添加参数的类型来执行那个方法
			System.out.println(m.add(1, 2));	// 执行重写成功
			// 静态方法不能重写的例子
<strong><span style="color:#ff0000;">			System.out.println(m.sub(1, 2));	// 执行重写成功</span></strong>
			// 【案2】
			math m2 = new chapter8_math();				//创建了一个对象实例math的子类chapter8_math的实例,它的对象引用为m
			System.out.println(m2.add(1.0f, 2.3f));		//执行重载方法,根据添加参数的类型来执行那个方法
			System.out.println(m2.add(1, 2));	// 执行重写成功
			// 静态方法不能重写的例子
<strong><span style="color:#ff0000;">			System.out.println(m2.sub(1, 2));	// 执行重写不成功</span></strong>
			
<span style="white-space:pre">			</span>// 【案3】
			math m3 = new math();				//创建了一个对象实例math,它的对象引用为m
			System.out.println(m3.add(1.0f, 2.3f));		//执行重载方法,根据添加参数的类型来执行那个方法
			System.out.println(m3.add(1, 2));	// 执行重写不成功?不是,因为根本就不是重写
			// 静态方法不能重写的例子
			System.out.println(m3.sub(1, 2));	// 执行重写不成功?不是,因为根本不是重写
			
		}	
}

运行的结果如下:

3.3
1

2


3.3
1

-1


3.3
3
-1

小结:

1 重载和重写的区别

重载和重写很好区别,看看接口是否一致。【案1,2,3】都很好的诠释了这一点。由于重载本身就是父类里面的,所以毫无疑问,所有的输出都是3.3

2 静态方法不能重写 - 【hsy75案】书上的这个定义是正确的么???

2.1 看【案0】父类是静态子类是public,或者父类是public子类是静态,这两种都是JAVA不支持,编译都无通过。

2.2 静态方法是属于类的,而属于类其实就是属于编译的。

首先我们看【案1】和【案2】的区别,他们都创建了chapter8_math的实例,但是,有一个不同,就是对象的应用类型不同,对象的引用类型不同,导致了编译器的类型不同,编译器类型的不同,导致了static静态方法和静态成员变量的作用开始发挥了。

无论是先编译math,或者是chaper8_math(math的子类),只要创建的是chapter8_math实例,由于父类中申明为pubilc的add方法,显然在子类都被有效的重写了。

当然,当我们疑惑【案3】的时候,我们也许忽略了,【案3】创建的是math实例,所以从编译到堆都是典型的父类,所以,这里根本就不是重写的操作。


现在,有关于static修饰的静态方法问题的关键点出来了,

现在申明为static的sub方法,显然由于对象的引用类型不同,或者说是编译的类不同,导致了重写的不同结果,失败和成功。

从结果打印可以看到,只要对象的引用声明是chapter_math,也就是先编译的是子类,自然,子类的static方法就重写了父类的方法了。

也就是作者说的静态方法不能重写是错误的,只要我们在对象申明时候引用子类的名称就好了,是可以重写的。


3 你也许会困惑书中所说覆盖和重写的区别

其实,简单覆盖就是父类的成员变量的重写,就是重写的一种形式,或者,说重写是方法的覆盖而已。


本帖原创,转贴请注明出处,完全是自己的想法,如果有错误,还请和

hsy_work@163.com 联系




JAVA 的面向对象设计的特点-书后感-01-21天学通JAVA-深入分析