05继承与多态

一、 继承条件下的构造方法调用

1、运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!

源代码:

package lianxi7;

class GrandParent

{

public GrandParent()

{

System.out.println("GrandParent Created");

}

public GrandParent(String string)

{

System.out.println("GrandParent Created.String:"+string);

}

}

class Parent extends GrandParent{

public Parent(){

super("sdg");

System.out.println("Parent Created");

}

}

class Child extends Parent{

public Child(){

System.out.println("Child Created");

}

}

public class TestInherits {

public static void main(String[] args) {

// TODO Auto-generated method stub

Child c=new Child();

}

}

实验结果截图:

结论:通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句,必须写在第一个。

2、为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?

子类是通过父类继承过来的,所以子类有父类的属性和方法,如果不调用父类的构造方法,那么怎么初始化父类中定义的属性,即怎么给父类的属性分配内存空间 ,如果父类的属性没有分配内存空间,那么子类访问父类的属性,就会报错。

二、神奇的“+”号

注意最后一句,一个字串和一个对象“相加”,得到以下结果:

在“+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。

三、请自行编写代码测试以下特性: 在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。

源代码:

class GrandParent

{

public GrandParent()

{

System.out.println("GrandParent Created");

}

public GrandParent(String string)

{

System.out.println("GrandParent Created.String:"+string);

}

}

class Parent extends GrandParent{

public Parent(){

super("sdg");

System.out.println("Parent Created");

}

}

class Child extends Parent{

public Child(){

System.out.println("Child Created");

}

}

public class TestInherits {

public static void main(String[] args) {

// TODO Auto-generated method stub

Child c=new Child();

}

}

实验截图为:

未添加super("sdg")之前的结果:

课后作业一:接口多态:使用接口代替抽象基类
一、源代码
package zoo4;

import java.util.Vector;

public class Zoo2 {

public static void main(String args[]) {

Feeder f = new Feeder("小李");

Vector<Animal> ans = new Vector<Animal>();//可随时向其中加入或移除对象

//饲养员小李喂养一只狮子

ans.add(new Lion());

//饲养员小李喂养十只猴子

for (int i = 0; i < 10; i++) {

ans.add(new Monkey());

}

//饲养员小李喂养5只鸽子

for (int i = 0; i < 5; i++) {

ans.add(new Pigeon());

}

f.feedAnimals(ans);

}

}

class Feeder {

public String name;

Feeder(String name) {

this.name = name;

}

public void feedAnimals(Vector<Animal> ans) {

for (Animal an : ans) {

an.eat();

}

}

}

interface Animal {

public void eat();

}

class Lion implements Animal {

public void eat() {

System.out.println("我不吃肉谁敢吃肉!");

}

}

class Monkey implements Animal {

public void eat() {

System.out.println("我什么都吃,尤其喜欢香蕉。");

}

}

class Pigeon implements Animal {

public void eat() {

System.out.println("我要减肥,所以每天只吃一点大米。");

}

}

二、实验运行截图

验证:

①TestInstanceof.java

代码

public class TestInstanceof

{

public static void main(String[] args)

{

//声明hello时使用Object类,则hello的编译类型是Object,Object是所有类的父类

//但hello变量的实际类型是String

Object hello = "Hello";

//String是Object类的子类,所以返回true。

System.out.println("字符串是否是Object类的实例:" + (hello instanceof Object));

//返回true。

System.out.println("字符串是否是String类的实例:" + (hello instanceof String));

//返回false。

System.out.println("字符串是否是Math类的实例:" + (hello instanceof Math));

//String实现了Comparable接口,所以返回true。

System.out.println("字符串是否是Comparable接口的实例:" + (hello instanceof Comparable));

String a = "Hello";

//String类既不是Math类,也不是Math类的父类,所以下面代码编译无法通过

//System.out.println("字符串是否是Math类的实例:" + (a instanceof Math));

}

}

运行结果截图:

②TestCast.java

代码如下:

class Mammal{}

class Dog extends Mammal {}

class Cat extends Mammal{}

public class TestCast

{

public static void main(String args[])

{

Mammal m;

Dog d=new Dog();

Cat c=new Cat();

m=d;

//d=m;

d=(Dog)m;

//d=c;

//c=(Cat)m;

}

}

运行结果没有出错!

③Zoo.java

代码如下:

package zoo4;

import java.util.Vector;

public class Zoo {

public static void main(String args[]) {

Feeder f = new Feeder("小李");

Vector<Animal> ans = new Vector<Animal>();//可随时向其中加入或移除对象

//饲养员小李喂养一只狮子

ans.add(new Lion());

//饲养员小李喂养十只猴子

for (int i = 0; i < 10; i++) {

ans.add(new Monkey());

}

//饲养员小李喂养5只鸽子

for (int i = 0; i < 5; i++) {

ans.add(new Pigeon());

}

f.feedAnimals(ans);

}

}

class Feeder {

public String name;

Feeder(String name) {

this.name = name;

}

public void feedAnimals(Vector<Animal> ans) {

for (Animal an : ans) {

an.eat();

}

}

}

abstract class Animal {

public abstract void eat();

}

class Lion extends Animal {

public void eat() {

System.out.println("我不吃肉谁敢吃肉!");

}

}

class Monkey extends Animal {

public void eat() {

System.out.println("我什么都吃,尤其喜欢香蕉。");

}

}

class Pigeon extends Animal {

public void eat() {

System.out.println("我要减肥,所以每天只吃一点大米。");

}

}

运行结果截图:

时间: 2024-07-31 21:12:06

05继承与多态的相关文章

课堂作业05继承与多态

第七讲  继承与多态 一.为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来? 1. 由于子类是继承父类的,所以想用子类创建对象时,必须先创建父类的对象,这样子类才能有父类的属性和方法.在创建对象时如果父类的数据需要进行初始化,那么就需要调用父类的构造函数,使构造函数初始化. 2. 不能反过来 3. 原因:因为父类不知道子类有什么属性,而且反过来子类也不能得到父类初始化的变量. 二.运行以下测试代码: 1. 左边的程序运行结果是什么? 1. 你如何解释会得到这

网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档

小总结: 所用技术: 01.C/S架构,数据存储在XML文件中 02.简单工厂模式 03.继承和多态 04.解析XML文档技术 05.深入剖析内存中数据的走向 06.TreeView控件的使用 核心:通过该项目,我们对业务流程有一个整体把控.对继承和多态有深入的了解 下面是类图: 主界面图: 核心思路: 1   1.首先在频道管理类ChannelManager中写一个加载所有频道方法LoadAllChannel; 2   3        该方法作用读取FullChannels.xml文件,并且

05 继承

继承与相等测试 (objectA instanceof Class) 返回 boolean 对象相等( 堆内存中) aObject.equals(bObject) 以上两个方法属于 Object 类, 所以所有的类都可以使用. 反射 反射库提供了一个非常丰富且精心设计的工具集, 以便编写能够动态操作java代码的程序, 这项功能被大量的应用于javabeans中. 能够分析类能力的程序被称为反射(reflective) java 反射机制是在运行状态中, 对于任意一个类, 都能够知道这个类的所有

2、C#面向对象:封装、继承、多态、String、集合、文件(上)

面向对象封装 一.面向对象概念 面向过程:面向的是完成一件事情的过程,强调的是完成这件事情的动作. 面向对象:找个对象帮你完成这件事情. 二.面向对象封装 把方法进行封装,隐藏实现细节,外部直接调用. 打包,便于管理,为了解决大型项目的维护与管理. 三.什么是类? 将相同的属性和相同方法的对象进行封装,抽象出 “类”,用来确定对象具有的属性和方法. 类.对象关系:人是类,张三是人类的对象. 类是抽象的,对象是具体的.对象可以叫做类的实例,类是不站内存的,对象才占内存. 字段是类的状态,方法是类执

Java的继承与多态

Java的继承与多态对于提高开发效率,减少开发量,是非常有帮助的,也便于代码维护.下面是根据书上讲的,我又做了改进的例子. 假设需求: 公司需要对所有人员进行管理,所有人员分为普通员工和经理人,他们的头衔.工资.生日等信息都是不一样的,但是不能开发两套系统分别进行管理,而是要一套系统完成对所有人的管理. 设计一个员工类,这是父类,定义如下: package com.myHelloWorld; import java.text.ParseException; import java.text.Si

Java 继承、多态与类的复用

摘要: 本文结合Java的类的复用对面向对象两大特征继承和多态进行了全面的介绍. 首先,我们介绍了继承的实质和意义,并探讨了继承,组合和代理在类的复用方面的异同.紧接着,我们依据继承引入了多态.介绍了它的实现机制和详细应用.此外,为了更好地理解继承和多态.我们对final关键字进行了全面的介绍. 在此基础上.我们介绍了Java中类的载入及初始化顺序.最后.我们对面向对象设计中三个十分重要的概念–重载.覆盖与隐藏进行了详细的说明. 要点: 继承 组合,继承,代理 多态 final 关键字 类载入及

JAVA基础——面向对象三大特性:封装、继承、多态

JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据.     隐藏类的实例细节,方便修改和实现. 3.封装的实现步骤 需要注意:对封装的属性不一定要通过get/set方法,其他方法也可以对封装的属性进行操作.当然最好使用get/set方法,比较标准. A.访问修饰符 从表格可以看出从上到下封装性越来越差. B.this关键字 1.this关键字代表当前

Objective-C的封装、继承与多态

面向对象有三大特征:封装.继承和多态. 一.封装 封装是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问.简而言之,信息隐藏,隐藏对象的实现细节,不让用户看到,以此来增强安全性和简化编程,进而达到封装的目的. 使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问权限来使用类的成员. 访问修饰符:private.protect.public private:私有的,不可供外部访问的信息,只有类本身能存取. prot

【转】C#三大特性之 封装、继承、多态

C#三大特性之 封装.继承.多态 一.封装: 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类).被封装的对象通常被称为抽象数据类型.  封装的意义: 封装的意义在于保护或者防止代码(数据)被我们无意中破坏.在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改. 封装提供了一个有效的途径来保护数据不被意外的破坏.相比我们将数据(用域来实现)在程序中定义为公用的(public)我们将它们(fie