zoukankan      html  css  js  c++  java
  • Java开发笔记(四十八)类的简单继承

    前面介绍了类的基本用法,主要是如何封装一个类的各项要素,包括成员属性、成员方法、构造方法等,想必大家对类的简单运用早已驾轻就熟。所谓“物以类聚,人以群分”,之所以某些事物会聚在一起,乃是因为它们拥有类似的品性。那么面向对象的目的,就是将一群事物之间共同的行为特征提炼出来,从而归纳为具有普适性的类型。像日常生活中说的昆虫、鱼类、鸟类,便是人们把外表相似、习性相近的一系列动物归类的结果。
    以鸟类为例,按照科学家的定义,它们是动物界→脊索动物门→鸟纲下面所有动物的总称。倘若按照大众的观点,鸟类为长着一对翅膀和两条腿的有羽动物的统称,特别是羽毛把鸟类与各种昆虫以及蝙蝠区别开来。假设现在有一群鸟类,需要通过几项特征将它们区分开,则可提问几个为什么,诸如它的名称是什么、它的叫声是什么、它的性别是什么等等。这些用来区别鸟儿个体的特征,对应于面向对象理论的属性概念,那么在Java编程之中,可以设计一个名叫Bird的鸟类,并给Bird类定义名称、叫声、性别等成员属性,以及读写属性的成员方法,如此便构成了程序世界里面的鸟类定义。
    至于Bird类的具体定义,相信大家参照之前的类封装,即可轻车熟路填写其中的成员属性、成员方法,乃至构造方法等要素。下面是一个Bird类的详细定义代码例子:

    public class Bird {
    	// 定义鸟的名称
    	private String name;
    	// 定义鸟的叫声
    	private String voice;
    	// 定义鸟的性别类型。0表示雄性,1表示雌性
    	private int sexType;
    	// 定义鸟的性别名称
    	private String sexName;
    	
    	// 鸟类的构造方法(无任何输入参数)
    	public Bird() {
    		this.name = "鸟";
    	}
    
    	// 鸟类的构造方法(输入参数包含:名称、性别、叫声)
    	public Bird(String name, int sexType, String voice) {
    		this.name = name;
    		this.voice = voice;
    		setSexType(sexType); // 该方法内部同时修改性别类型和性别名称
    	}
    	
    	// 设置鸟的名称
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	// 获取鸟的名称
    	public String getName() {
    		return this.name;
    	}
    
    	// 设置鸟的叫声
    	public void setVoice(String voice) {
    		this.voice = voice;
    	}
    
    	// 获取鸟的叫声
    	public String getVoice() {
    		return this.voice;
    	}
    
    	// 设置鸟的性别类型,并自动调整性别名称
    	public void setSexType(int sexType) {
    		this.sexType = sexType;
    		this.sexName = (sexType==0) ? "雄" : "雌";
    	}
    
    	// 获取鸟的性别类型
    	public int getSexType() {
    		return this.sexType;
    	}
    
    	// 获取鸟的性别名称
    	public String getSexName() {
    		return this.sexName;
    	}
    
    	// 输出鸟类的基本信息描述文字
    	public String toString() {
    		String desc = String.format("这是一只%s%s,它会%3$s、%3$s地叫。", 
    				this.sexName, this.name, this.voice);
    		return desc;
    	}
    }
    

    有了上面的鸟类定义,然后外部才能按部就班地使用Bird类,譬如通过Bird声明一只鸽子的实例,则相关的调用代码如下所示:

    		// 创建一个鸟类的实例
    		Bird pigeon = new Bird();
    		pigeon.setName("鸽子");
    		pigeon.setSexType(1);
    		pigeon.setVoice("咕咕");
    		System.out.println(pigeon.toString());
    

    运行以上的代码例子,可观察到以下的日志输出结果:

    这是一只雌鸽子,它会咕咕、咕咕地叫。
    

    可是鸽子并非单独的一种鸟类,而是鸟纲→鸽形目→鸠鸽科→鸽属下面所有鸽类的统称,包括家鸽、岩鸽、银鸽、雪鸽、斑鸽、黄腿鸽、白头鸽等等,这些鸽类动物相互之间具备更接近的习性特征,理应拥有自己的类定义如Pigeon类。
    考虑到所有的鸟类动物都存在大类之下再分小类的需求,小类在大类的基础上再体现本类的特色属性,故而定义小类之时不必另起炉灶,完全可以基于大类然后修修补补形成新的小类定义。这种小类基于大类的关系,在面向对象体系中被称作“继承”,意思是小类继承了大类的所有成员,大类更专业的称呼叫“基类”,基于大类的小类也被起了个大名叫做“派生类”。
    现在就以前述的Bird为基类,给它扩展出一个新的派生类Swallow(燕子类),准备把鸟纲→雀形目→燕科下面的家燕、雨燕、金丝燕等包罗在内。Java代码中表示继承关系的关键字是extends,从A类派生出B类的写法为“class B extends A”,其余的类定义框架保持不变。于是从Bird派生而来的Swallow类定义代码示例如下:

    //定义了一个继承自鸟类的燕子类
    public class Swallow extends Bird {
    	// 燕子类未重写任何构造方法,则默认使用不带输入参数的构造方法
    }
    

    仅仅看Swallow类的代码定义,发现内部空空如也,其实它早已继承了Bird类的所有成员属性和成员方法,以及默认的构造方法。外部使用Swallow类的时候,就像操作Bird类一样的用法,比如下面代码演示了如何创建燕子类的实例、以及如何调用该实例的方法:

    		// Swallow类使用不带任何参数的默认构造方法
    		Swallow swallow = new Swallow();
    		swallow.setName("燕子");
    		swallow.setSexType(0);
    		swallow.setVoice("啾啾");
    		System.out.println(swallow.toString());
    

    运行上面的演示代码,可以看到下述的日志信息:

    这是一只雄燕子,它会啾啾、啾啾地叫。
    

    由此可见Swallow类的确完整继承了Bird类的所有成员。



    更多Java技术文章参见《Java开发笔记(序)章节目录

  • 相关阅读:
    LeetCode 326. Power of Three
    LeetCode 324. Wiggle Sort II
    LeetCode 322. Coin Change
    LeetCode 321. Create Maximum Number
    LeetCode 319. Bulb Switcher
    LeetCode 318. Maximum Product of Word Lengths
    LeetCode 310. Minimum Height Trees (DFS)
    个人站点大开发!--起始篇
    LeetCode 313. Super Ugly Number
    LeetCode 309. Best Time to Buy and Sell Stock with Cooldown (DP)
  • 原文地址:https://www.cnblogs.com/pinlantu/p/10262389.html
Copyright © 2011-2022 走看看