首页 > 代码库 > 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-深入分析