搜索
写经验 领红包
 > 职场

多态java例子(java中多态的含义)

导语:初识Java—(二十)多态的示例

多态java例子(java中多态的含义)

继承是实现类重用的重要手段,但是继承带来了一个最大的坏处:破坏封装。相比之下,组合也是实现类重用的重要方式,而采用组合方式来实现类重用并能提供更好的封装。下面详细介绍继承和组合之间的联系与区别。

5.8.1 使用继承的注意点

子类扩展父类时,子类可以从父类继承得到Filed和方法。如果访问权限允许,子类可以直接访问父类的Field和方法,相当于子类可以直接复用父类的Field和方法。继承带来了高度复用的同时,也带来了一个严重的问题:那就是继承严重破坏了父类的封装性。封装:每个类都不可以随意访问其父类的Field和方法,父类只需要暴漏必要的方法给其他类使用。但是在继承关系中,子类可以直接访问父类的Field和方法,从而造成子类与父类的严重耦合。

父类的实现细节对于子类来说不再透明,子类可以访问父类的Field和方法,并可以改变父类的方法的实现细节,从而导致子类可以任意的篡改父类的方法和属性(Field)

举例1:

package com.langsin.test;public class Bird {public String name = &34;;public void fly(){System.out.println(this.name+&34;);}Public void run(){this.fly();}}

篡改属性:

package com.langsin.test;public class Ostrich extends Bird {public void test(){this.name = &34;; //任意篡改了父类的属性信息this.fly();}public static void main(String[] args) {Ostrich os = new Ostrich();os.test();}}

篡改方法:

package com.langsin.test;public class Ostrich extends Bird {public void test(){this.fly();}//任意篡改方法public void fly(){System.out.println(this.name+&34;);}public static void main(String[] args) {Ostrich os = new Ostrich();os.test();}}

对于此种问题,基于保证父类有良好的封装,不会被子类随意改变,设计父类时通常遵循如下规则:

1、 尽量隐藏父类的内部数据,尽量把父类的所有Field都设置成private访问类型,不让子类直接访问父类的Field.

2、 不要让子类可以随意访问、修改父类的方法。父类中作为辅助其他方法的工具方法,应该使用private访问控制符修饰,让子类无法访问该方法。如果父类中的方法需要被外部类调用,则必须以public修饰,但又不希望被子类重写该方法,可以使用final修饰符来修饰,表示最终的方法。如果父类的方法可以让子类重写,但是又不希望被其他类自由访问,可以使用protected来修饰该方法。

3、 不要在父类构造方法中调用将会被子类重写的方法。因为如果方法被子类重写,那么子类在实例化时,会调用父类的构造方法来进行父类初始化时,构造方法中调用的是被子类重写的方法,而不是本身的那个方法。

举例2:

package com.langsin.test;public class Bird {Bird(){this.fly();}public void fly(){System.out.println(&34;);}}package com.langsin.test;publicclass Ostrich extends Bird {public void fly(){System.out.println(&34;);}public static void main(String[] args) {Ostrich os = new Ostrich(); //在创建子类对象时,父类构造方法调用了被子类重写的方法。}}

注意:如果把某些类设置成最终类,即使用final修饰符修饰这个类,那么这个类将不能被当成父类。例如JDK所提供的java.lang.String类,java.lang.System类,都是最终类。

5.8.2 利用组合实现复用

如果需要复用一个类,除了把这个类当成父类来继承之外,还可以把该类当成另外一个类的组成部分,从而允许新类直接复用该类的public方法。因此,不管是继承还是组合,都允许在新类中直接复用旧类的方法。

举例1:

package com.langsin.basic;//商品类public class Product {// 成员变量都是私有的。如果用到多个类中有成员变量是重复的,尽量把成员变量和方法分别开来。private String p_name;private String p_price;private String p_num;public Product(){}public Product(String p_name, String p_price, String p_num) {this.p_name = p_name;this.p_price = p_price;this.p_num = p_num;}public String getP_name() {return p_name;}public void setP_name(String p_name) {this.p_name = p_name;}public String getP_price() {return p_price;}public void setP_price(String p_price) {this.p_price = p_price;}public String getP_num() {return p_num;}public void setP_num(String p_num) {this.p_num = p_num;}}package com.langsin.basic;//订单类public class Order {private String orderName;private String date;private String orderId;private double money;private Product[] prods = null;Order(String orderName,String date,String orderId){this.orderId = orderId;this.date = date;this.orderName = orderName;}public Product[] getProds() {return prods;}public void setProds(Product[] prods) {this.prods = prods;}public String getOrderName() {return orderName;}public void setOrderName(String orderName) {this.orderName = orderName;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}public static void main(String[] args) {Product[] prods = new Product[3];Product p1 = new Product(&34;,&34;,&34;);Product p2 = new Product(&34;,&34;,&34;);Product p3 = new Product(&34;,&34;,&34;);prods[0] = p1;prods[1] = p2;prods[2] = p3;//商品购买完成Order order = new Order(&34;,&34;,&34;);order.setProds(prods);//查看此订单的详细信息System.out.println(&34;+order.orderName +&34;+order.date);System.out.println(&34;);for(int i=0;i<order.getProds().length;i++){Product prod = order.getProds()[i];//System.out.println(&34;+prod.getP_name()+&34;+prod.getP_price()+&34;+prod.getP_num());}}}

本文内容由小梓整理编辑!