java基础(第一篇)继承与组合

前言

本文讲述上篇文章《java基础(第零篇)对象与类》遗留的问题继承与组合的区别,在讲述区别之前。先讲述继承的有关概念,如果你对继承很清楚的可以直接拉到下面阅读继承与组合的区别。

继承是什么?

继承是面向对象三大特性之一。子类继承父类的特征和行为,使得子类对象拥有父类的属性和方法。子类亦可扩展其自己的方法。

继承的特点

  • 子类通过关键字extends 实现对父类的继承
  • 子类只可继承来自父类的除私有的属性和方法,对于包访问权限的属性和方法只能被同个包内的子类继承。
  • 构造方法不能被继承。
  • 静态方法和静态变量可以被继承。
  • java中,类之间只可单继承,即一个类只能继承一个父类。
  • 接口亦可继承另一个接口,但是接口可以多继承。
  • 继承的变量和方法可以覆盖。
  • 方法重写不允许降低访问权限。
  • 继承是紧耦合的。

protected 关键字作用

为了封装性,尽量隐藏对象的属性,会使用private关键字修饰,但是这样一来,如果这些属性除了对外隐藏外,还允许子类继承访问,那么protected关键字就派上用场了。

重写和重载

继承可以对父类的方法进行重写覆盖,而重载的概念并不是继承的一部分,重载是指类本身的方法通过参数表的不同进行重载,是编译时多态的实现方法。

举个栗子:

public class A extends B{
    public void method(){
        
    }
    public void method(int a){
        
    }
}
public class B{
    public void method(){
        
    }
}

上面的A类继承了B类,其中void method方法是父类B所拥有的,但是子类对其进行了重写覆盖,这就是重写。而A类中的 void method(int a); 则是A类的method方法进行重载。通过方法参数表进行区分重载。

另外,静态方法不能重写,因为重写指的是根据运行时对象的类型来决定调用哪个方法,而不是编译时的,类静态方法是编译时确定的,即使你在子类中定义了一个和父类一样的静态方法,编译器也不会报错,从多态的角度看,这并不是对静态方法的重写,而是子类自己的方法。

看个代码就知道了:

public class Base{
    public static void staticMethod(){
        System.out.println("父类静态方法执行了..");
    }
}

public class Son extends Base{
    public static void staticMethod(){
        System.out.println("子类静态方法执行了..");
    }
}

/*测试类*/
public class Test{
    public static void main(String[] args){
        Base b = new Son();
        b.staticMethod();//1. 
        b = new Base();
        b.staticMethod();//2. 
        Son son = new Son();
        son.staticMethod();//3.
    }
}

运行结果:


运行结果

按照实例方法的重写的规律,如果该方法是重写,那么代码第一处的执行应该是执行子类的重写方法,但是事实却未如此。由此看来,子类中看似重写的静态方法实际上不算一种重写。

final 关键字

  • 当一个类使用了final关键字进行修饰时,这个类不允许被继承
  • 当一个类的实例方法使用了final关键字进行修饰时,这个方法不允许子类重写。
  • 当一个类的属性使用了final关键字进行修饰时,这个属性不允许二次赋值,并且最晚需在构造方法中赋值,否则编译器会报错。

继承与组合的区别(重点)

继承:

优点:

(1) 子类自动继承父类接口,在多态时很方便
(2) 创建子类时无需创建父类对象

缺点:

(1) 继承破坏封装性

给父类增加了一个方法A,这时子类与父类之间就可能越来越脱离is-a
举个例子:比如,鸟类有羽毛等属性,这里有一个需求是,定义一个有羽毛的鸡类,采用继承的方法很优雅也很方便,直接一个extends 就可以实现,但是如果有一天,这个鸟类添加了一个飞翔的公有方法,此前继承了鸟类的鸡类会自动继承了这个方法,鸡会飞翔?顶多就是矮距离飞跃。此时给鸡飞的方法就是破坏了鸡的封装性,鸡不应该有此方法。此时的鸡已经和有飞翔行为的鸟类之间不是is-a 关系了。

(2) 继承是紧耦合:

继承紧耦合体现在父类变就会影响子类,此时子类如果因此需要修改,重构的难度可能会很高。

(3) 子类对父类的扩展往往会增加系统结构复杂度

继承树深度加深,结构越复杂。

(4) 不支持在运行时指定父类

(5) 子类不能改变父类的接口

组合

什么是组合?给个代码

public class A{
    public void a1(){}
    public void a2(){}
}

public class B{
    private A a = new A();
    public void a1(){
        a.a1();
    }
    public void a2(){
        a.a2();
    }
}

其中B类对A类这种复用的形式就是组合,这个是通过包装和方法转发实现的。

接下来讲述组合优缺点

优点

  1. 组合不破坏封装,相对于继承
  2. 组合松耦合,包装类和被包装类彼此独立,不会因为被包装类突然加个方法就使得包装类多了一个方法,包装类视情况包装所需方法。
  3. 支持动态组合,组合的方式在运行时可以根据条件来选择所组合的类。
  4. 包装类可以通过包装改变被包装类的接口,比如被包装类是实现了Set接口的,我可以通过包装,让包装类实现Map接口。

缺点

  1. 不能实现多态
  2. 无法自动获得被包装类的接口,比如被包装类实现了Set接口,包装类并没有自动获得此接口,需要经过包装,才有可能和他一样的接口。

何时用继承,何时用组合

这应该才是我们关心的问题吧。
在以下几种情况使用组合:

  1. 子类只需要继承父类的一部分,继承就没辙了。
  2. 如果只是为了具有父类的一些属性方法,比如汽车具有轮胎和发动引擎,但是如果为此继承这两个类是很不明智的,使用组合更为恰当。
  3. 如果设计的子类是为了复用代码,并不是为了扩展父类,那么最好是选组合的方式,因为父类改变会影响子类。对于只是为了复用而继承的类很不利。

什么时候使用继承?

  1. 类之间很明显是一种is-a 关系,而不是has-a或者contain-a关系。
  2. 考虑多态时使用继承

另外:

组合优于继承是面向对象设计原则之一

但我觉得也不能像滥用继承一样,一味地使用组合,该用继承的时候还是继承为佳。

以上是个人看法,可能不完全对,如有误,欢迎指教。

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,504评论 18 399
  • 转自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帅199207阅读 8,474评论 3 93
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,607评论 0 11
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,030评论 0 62
  • 今天想说什么呢?说说上午上班的时候偷偷和同事聊微信的内容吧。 我和同事A上礼拜一同一天来到这家公司,不...
    __小城月光阅读 97评论 0 0