继承设计的技巧
下面是一些对设计继承关系的建议
1、将公有成员放在超类中
这里的成员包括成员变量和成员方法。这样既可以减少代码的重复编写,避免出错(代码越多,越容易出错);还可以增强封装性,是程序更健壮。
2、尽量不要使用受保护的变量(即被protected修饰)
很多人认为,将大多数的实例变量定义为protected是很不错的,这样的话,子类就能在需要的时候直接访问它们了。但是,使用protected修饰并不能得到更好的保护作用,究其原因在于:第一、子类如果不被声明为final的话,其他程序员是可以向下派生出子类的,这样就可以直接访问该类中protected的成员,那么,所谓的封装性就会被破坏了。第二、protected修饰的成员是可以被同一包中的所有类访问的,无论是不是这个类的子类,这样,依然是对数据产生一定的危险。
3、使用继承实现字父类关系
使用继承可以节省很多的代码,但是要防止被随意使用。比如说,钟点工同样有姓名和年龄,但是他们和公司雇员是不一样的,是没有所谓的工资的,因为他们是按小时获得劳动报酬的。不会有雇员一样的薪资待遇的。所以,如果在Employee类(假设有一个Manager子类)再派生出一个子类Contrator,显然是不合理的,因为在Employee中的类似打印工资单的方法,是不适用于钟点工的。所以说,要清楚是否两个类之间有子父类的关系,在使用继承。
4、使用继承的方法有有意义,否则不要使用继承关系
对于可以相互转换的两类事物,使用继承是不好的。比如说,假日也是一天,可将假日作为一周或一个月的子类考虑,但是假日是可以转换为非假日的,那么这就不太合适了。
5、在覆盖方法时,不要改变预期的行为
在覆盖一个方法的时候,不应该随意改变行为的内涵,应该是由于超类的方法不适宜子类的应用,或者有缺陷的时候,才覆盖该方法。如果我们自己不慎重考虑覆盖的方法是否有意义,编译器是不会知道该方法是否有任何意义,只要语法没有错误,是可以通过编译的。
6、使用多态,而非类型信息
对于下面的代码:
if(x is of type1)
        action1(x);
else if(x is of type2)
        action2(x);



这就需要考虑使用多态了。
如果action1action2表示的是相同的内容,就可以定义一个方法,将其放置在两个类的超类或者接口中,然后就直接调用x.action(),因为JVM虚拟机可以动态绑定x是属于那种类型,这样可以节省很多代码,提高执行效率,而且更有利于对代码进行维护和扩展。
下面是举例:
class Employee
{
        //将变量定义为private
        private String name;
        private double salary;
        public Employee(String name,double salary){
                this.name = name;
                this.salary = salary;
        }
        public String getName(){
                return name;
        }
        public double getSalary(){
                return salary;
        }
        public void setSalary(double salary){
                this.salary = salary;
        }
}
class Manager extends Employee{
        private double bonus = 0;
        public Manager(String name,double salary){
                //调用超类Employee中的构造器
                super(name,salary);
        }
        //获得Manager类中对象的salary,有额外的奖金
        public double getSalary(){
                double baseSalary = super.getSalary();
                return baseSalary + bonus;
        }
        public void setBonus(double bonus){
                this.bonus = bonus;
        }
}
class ManagerText{
        public static void main(String [] args){
                Manager boss = new Manager("Anna",80000);
                boss.setBonus(5000);
                Employee[] staff = new Employee[3];
                staff[0] = boss;//由于boss是Manager类的,是Employee的子类,所以,是可以赋值给staff数组中的元素的
                staff[1] = new Employee("Ben",50000);
                staff[2] = new Employee("Jone",40000);
                for(int i=0;i<staff.length;i++){
                        System.out.println("name = " + staff[i].getName() + ",salary = " + staff[i].getSalary());
                }
        }
}



7不要过多的使用反射
反射机制使得人们可以通过在运行是查看变量和方法,让人们能编写出更具有通用性的程序。这种功能对于便携系统程序来说极其实用,但是通常不适用于编写应用程序。反射是很脆弱的,即编译器很难帮助人们发现程序中的错误。任何错误只能在运行时才被发现,并导致异常。