• 面向对象——继承与组合


    1、组合的特点

    2、继承带来最大的坏处

    3、设计父类遵循的规则

    4、何时使用继承

    5、何时使用组合

    1、组合的特点

        提高代码复用性,增加has-a关系,增强理解

    2、继承带来最大的坏处

        破坏父类的封装性(每个类都应该封装它内部信息和实现细节,而只暴露必要的方法给其他类使用。但继承关系中,子类可以直接访问父类的属性(内部信息)和方法,从而造成子类和父类的严重耦合)。采用组合方法来实现类重用则能提供更好的封装性。

    3、设计父类遵循的规则

    为了保证父类良好的封装性,不会被子类随意改变,设计父类通常应该遵循以下规则:

    ① 尽量隐藏父类的内部数据(private);

    ② 不要让子类可以随意访问、修改父类的方法。辅助方法设为private,需要被外部调用public,不希望子类重写加上final,若希望重写但是不希望其他类自由访问,设为protected;

    ③ 在父类构造器中不调用被子类重写的方法(否则会引起空指针异常)。

    比如:new 父类时调用的是父类自己的方法,而通过子类new一个父类时,在父类构造器中实际上调用的是子类方法。

    例1

    public class FatherSonTest {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Father f = new Son();
            f.getNum();
        }
    
    }
    class Father{
        private int num;
        public Father() {
            num = getNum();
            System.out.println("Father, num="+num);
        }
        public int getNum() {
            System.out.println("this is Father!");
            return 4;
        }
    }
    class Son extends Father{
        private int num;
        public Son() {
            num = getNum();
            System.out.println("Son, num="+num);
        }
        public int getNum() {
            System.out.println("this is Son!");
            return 5;
        }
    }

    output:

    this is Son!

    Father, num=5

    this is Son!

    Son, num=5

    this is Son!

    例2:

    public class a { 
        public static void main(String[]args){  
            a c=new b();  
            //下面这里打印的是a的成员变量s=AAAA  
            System.out.println(c.s); 
        }
        public String s="AAAA";  
        //父类构造函数 
        public a(){  
            call(); 
        }
        public void call(){  
            System.out.println("a class call()="+s); 
        } 
    }
    class b extends a{ 
        public String s="BBBB"; 
        //子类构造函数 
        public b(){  
            System.out.println("b class b()="+s); 
        }
        //重写父类中的call函数 
        public void call(){  
            System.out.println("b class call()="+s); 
        }
    }

    output:

    b class call()=null

    b class b()=BBBB

    AAAA

    由于父类第一次调用子类的call方法时,子类还没有初始化非静态变量以及构造方法(静态成员被初始化了),因此输出是null。

    注意:通过父类的引用类型变量指向子类类型对象,访问成员变量时是访问的父类的成员变量。

    (类加载时会为静态变量赋初值,执行静态代码块,但不会为实例变量赋初值,只有构造函数执行时才会赋值)

    若希望某些类不被继承,可以用final修饰类,或者将所有构造器设为private,保证子类无法调用该类的构造器,从而无法继承。

    4、何时使用继承

    保证子类是一种特殊的父类,加上以下两个条件之一:

    ①   子类需要额外增加属性,而不仅仅是属性值的改变;

    ②   子类需要增加自己独有的行为方式。

    5、何时使用组合

    若只是出于类复用的目的,并不一定需要使用继承,完全可以使用组合来实现。

    通常将新类中嵌入旧的对象修饰为private

  • 相关阅读:
    tctip demo页面>
    tctip demo页面>
    tctip demo页面>
    tctip demo页面>
    tctip demo页面>
    tctip demo页面>
    tctip demo页面>
    tctip demo页面>
    tctip demo页面>
    sql 随笔
  • 原文地址:https://www.cnblogs.com/datamining-bio/p/13125938.html
Copyright © 2020-2023  润新知