Java第四次作业——面向对象高级特性(继承和多态)


(一)学习总结

1.学习使用思维导图对Java面向对象编程的知识点(封装、继承和多态)进行总结。

2.阅读下面程序,分析是否能编译通过?如果不能,说明原因。应该如何修改?程序的运行结果是什么?为什么子类的构造方法在运行之前,必须调用父 类的构造方法?能不能反过来?


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() {
System.out.println("Parent Created");
super("Hello.Grandparent.");
}
}
class Child extends Parent {
public Child() {
System.out.println("Child Created");
}
}
public class Test{
public static void main(String args[]) {
Child c = new Child();
}
}

编译不能通过,原因是继承父类的时候super关键字必须是第一条语句才可以继承;程序的运行结果为:

GrandParent Created.String:Hello.Grandparent.
Parent Created
Child Created

不可以,因为只有产生父类,实例化父类后才可以产生子类并且实例化。


3 . 阅读下面程序,分析程序中存在哪些错误,说明原因,应如何改正?正确程序的运行结果是什么?

class Animal{
void shout(){
System.out.println("动物叫!");
}
}
class Dog extends Animal{
public void shout(){
System.out.println("汪汪......!");
}
public void sleep() {
System.out.println("狗狗睡觉......");
}
}
public class Test{
public static void main(String args[]) {
Animal animal = new Dog();
animal.shout();
animal.sleep();
Dog dog = animal;
dog.sleep();
Animal animal2 = new Animal();
dog = (Dog)animal2;
dog.shout();
}
}

sleep函数属于子类,但不属于父类,所有父类不可以调用子类,Dog为子类,父类转为子类需强制转换。

class Animal{
void shout(){
System.out.println("动物叫!");
}
}
class Dog extends Animal{
public void shout(){
System.out.println("汪汪......!");
}
public void sleep() {
System.out.println("狗狗睡觉......");
}
}
public class Test{
public static void main(String args[]) {
Animal animal = new Dog();
animal.shout();
Dog dog = (Dog)animal;
dog.sleep();
Animal animal2 = new Animal();
if (animal2 instanceof Dog){
dog = (Dog)animal2;
dog.shout();
}
}
}

用instanceof关键字来判断是否是某个类的对象,返回boolean类型。如果在该程序没有使用instanceof则出现异常终止,所以该关键字可以预防异常终止的情况发生。


4运行程序

class Person {
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
}
public class Test{
public static void main(String args[]){
Person per = new Person("张三",20) ;
System.out.println(per);
System.out.println(per.toString()) ;
}
}

出现

Person@166afb3
Person@166afb3
(1)程序的运行结果如下,说明什么问题?

在Person类中没有定义方法toString(),故返回的是随机的地址需要添加方法toString。

class Person {
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
} public String toString() { return "name "+this.name+"age:"+this.age;
}
}
public class Test{
public static void main(String args[]){
Person per = new Person("张三",20) ;
System.out.println(per);
System.out.println(per.toString()) ;
}
}

(2)那么,程序的运行结果到底是什么呢?利用eclipse打开println(per)方法的源码,查看该方法中又调用了哪些方法,能否解释本例的运行结果?
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}

用到String.valueOf方法,将x转为String并传给s,进行输出

(3)在Person类中增加toString方法,重新运行程序,程序的执行结果是什么?说明什么问题?

覆写了toString方法


(二)实验总结

(1)实验内容:


定义员工类,具有姓名、年龄、性别属性,并具有构造方法和显示数据方法。定义管理层类,继承员工类,有自己的属性职务和年薪。定义职员类,继承员工类,并有自己的属性所属部门和月薪。定义一个测试类,进行测试。画出类图。

设计思路:定义员工类,然后管理层类职员类分别继承即可。


2.按照下面要求完成类的设计

程序设计思路:定义两个抽象类,分别为平面图形抽象类(提供求该类对象周长和面积的方法)和立体图形抽象类(提供求该类对象表面积和体积的方法),再分别定义一个球类、圆柱类,圆锥类、矩形类、三角形类、圆类,分别继承平面图形抽象类和立体图形抽象类。再定义一个测试类,对每个类设置数据进行输出。

平面类和立体类相似。

问题1:因为使用了math.PI,所以输出有小数

解决:使用 java.math.BigDecimal

问题2:圆锥体的计算方法

解决:添加一个变量,母线长l,并进行计算


3.1某动物园有一饲养员小李,每天需要给他所负责饲养的一只狮子、五只猴子和十只鸽子喂食。 请用一个程序来模拟他喂食的过程。



需要给每个对象创建类,然后实例化每个对象,

package feed;
public class Test {
public static void main(String args[]){
Feeder ia=new Feeder();
ia.setName("chen"); //初始化Feeder类并给出Feeder的姓名
Lion a=new Lion("meat","tim"); //实例化Lion
System.out.println("this is a lion:");
ia.feedLion(ia.getName(), a);
System.out.println("this is five monkeys:");
Monkey m[]=new Monkey[5]; //对象数组来实例化对象
m[0]=new Monkey("bannana","a");
m[1]=new Monkey("bannana","b");
m[2]=new Monkey("bannana","c");
m[3]=new Monkey("bannana","d");
m[4]=new Monkey("bannana","e");
for(int q=0;q<m.length;q++){
ia.feedMonkey(ia.getName(), m[q]); //用static来输出猴子的编号,鸽子同上
}
System.out.println("this is five pigeons:");
Pigeon p[]=new Pigeon[5];
p[0]=new Pigeon("xiaomai","ia");
p[1]=new Pigeon("xiaomai","ib");
p[2]=new Pigeon("xiaomai","ic");
p[3]=new Pigeon("xiaomai","id");
p[4]=new Pigeon("xiaomai","ie");
for(int i=0;i<p.length;i++){
ia.feedPigeon(ia.getName(), p[i]);
} }
}

然后用for循环输出。

缺点是,重复代码很多,尤其是每个类里面的重复代码块

3.2第一次重构,引入继承,利用抽象类和对象多态重构程序,Animal类采用抽象类, 合并Feeder类中的方法

创建抽象类Animal,这样可以节省各个类中的代码。将各个动物类继承该Animal类,需要注意的是在feeder类中需要实例化每个动物类的对象,这是因为在feeder类中需要调用每个类的对象。

package feedCons;
public class Feeder {
Lion l=new Lion();
Monkey m=new Monkey();
Pigeon p=new Pigeon();
private String feedername;
public Feeder(){ }
public Feeder(String feedername){
this.feedername=feedername;
}
public String getFeederName() {
return feedername;
}
public void setFeederName(String feedername) {
this.feedername = feedername;
}
public void feedAnimal(Lion l){
l.eat();
System.out.println("feed by "+this.feedername);
}
public void feedAnimal(Monkey m){
m.eat();
System.out.println("feed by "+this.feedername);
}
public void feedAnimal(Pigeon p){
p.eat();
System.out.println("feed by "+this.feedername);
}
}

3.3第二次重构,修改feedAnimals方法,让它接收一个Animal数组

package feedsec;
public class Feeder {
Lion l=new Lion();
Monkey m=new Monkey();
Pigeon p=new Pigeon();
public String name;
public Feeder(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void feedAnimal(Animal a[]){
for (int i = 0; i < a.length; i++){
a[i].toeat();
}
}
public void feeder(Animal animals){
System.out.println(" and feeder by "+this.name);
} }

通过数组调用每个对象的函数,减少代码。

package feedsec;
public class Test {
public static void main(String [] args){
Feeder feeder = new Feeder("chen");
Animal animals[]=null;
animals = new Animal[16];
animals[0] = new Lion("meat");
animals[0].toeat();
feeder.feeder(animals[0]);
for(int i = 0; i < 5; i++){
animals[i + 1] = new Monkey("banana");
animals[i+1].toeat();
feeder.feeder(animals[i]);
}
for(int i = 0; i < 10; i++){
animals[6 + i] = new Pigeon("xiaomai");
animals[6+i].toeat();
feeder.feeder(animals[i]);
} }
}

问题1:多个动物编号问题

解决:使用static关键字,定义个变量,在构造方法中使用setNum()方法来传给变量,变量++,需要静态代码块初始化变量。实例:

public class Monkey {
private String food;
private String name;
private int numb;
static int i;
static{
i=1000;
}
public Monkey(){ }
public Monkey(String food,String name){
setNumb(i);
i++; //猴子的编号
this.food=food;
this.name=name;
}

(三)代码托管

Java第四次作业——面向对象高级特性(继承和多态)的更多相关文章

  1. Java第四次作业—面向对象高级特性(继承和多态)

    Java第四次作业-面向对象高级特性(继承和多态) (一)学习总结 1.学习使用思维导图对Java面向对象编程的知识点(封装.继承和多态)进行总结. 2.阅读下面程序,分析是否能编译通过?如果不能,说 ...

  2. Java第四次作业--面向对象高级特性(继承和多态)

    一.学习要点 认真看书并查阅相关资料,掌握以下内容: 掌握类的继承概念和设计 掌握构造方法的继承原则 掌握方法重写 掌握super键字和final关键字 理解多态的概念,掌握通过方法重写和方法重载机制 ...

  3. Java第五次作业--面向对象高级特性(抽象类与接口)

    Java第五次作业--面向对象高级特性(抽象类与接口) (一)学习总结 1.在上周完成的思维导图基础上,补充本周的学习内容,对Java面向对象编程的知识点做一个全面的总结. 2.汽车租赁公司,出租汽车 ...

  4. Java第五次作业--面向对象高级特性(抽象类和接口)

    一.学习要点 认真看书并查阅相关资料,掌握以下内容: 掌握抽象类的设计 掌握接口的设计 理解简单工厂设计模式 理解抽象类和接口的区别 掌握包装类的应用 掌握对象的比较方法和比较器的使用 学习使用日期操 ...

  5. Java第四次作业,面向对象高级特性(继承和多态)

    Java第四次作业-面向对象高级特性(继承和多态) (一)学习总结 1.学习使用思维导图对Java面向对象编程的知识点(封装.继承和多态)进行总结. 2.阅读下面程序,分析是否能编译通过?如果不能,说 ...

  6. Java第三次作业——面向对象基础(封装)

    Java第三次作业--面向对象基础(封装) (一)学习总结 1.什么是面向对象的封装性,Java中是如何实现封装性的?试举例说明. 封装性 封装性是面向对象的方法所应遵循的一个重要原则,它有两个含义: ...

  7. [.net 面向对象编程基础] (12) 面向对象三大特性——继承

    [.net 面向对象编程基础] (12) 面向对象三大特性——继承 上节我们说了面向对象的三大特性之一的封装,解决了将对同一对象所能操作的所有信息放在一起,实现统一对外调用,实现了同一对象的复用,降低 ...

  8. Python3 与 C# 面向对象之~继承与多态 Python3 与 C# 面向对象之~封装 Python3 与 NetCore 基础语法对比(Function专栏) [C#]C#时间日期操作 [C#]C#中字符串的操作 [ASP.NET]NTKO插件使用常见问题 我对C#的认知。

    Python3 与 C# 面向对象之-继承与多态   文章汇总:https://www.cnblogs.com/dotnetcrazy/p/9160514.html 目录: 2.继承 ¶ 2.1.单继 ...

  9. C#基础总结之八面向对象知识点总结-继承与多态-接口

    .方法深入讲解(返回值,形参与实参) 方法 public int getName(int i,int j) { int sum = i + j; return sum; } .利用泛型存储对象数据 . ...

随机推荐

  1. This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.

    Attempt to load Oracle client libraries threw BadImageFormatException. This problem will occur when ...

  2. ApplicationCommands用于表示应用程序程序员经常遇到的常见命令,类似于ctrl+c

    在WPF中,许多控件都自动集成了固有的命令集.比如文本框TextBox就提供了复制(Copy),粘贴(Paste),裁切(Cut),撤消(Undo)和重做(Redo)命令等. WPF提供常用应用程序所 ...

  3. win10 uwp 如何判断一个对象被移除

    原文:win10 uwp 如何判断一个对象被移除 有时候需要知道某个元素是否已经被移除,在优化内存的时候,有时候无法判断一个元素是否在某个地方被引用,就需要判断对象设置空时是否被回收. 本文告诉大家一 ...

  4. C#基础加强篇—委托、Lambda表达式和事件(下)

    3.事件 事件作为C#中的一种类型,为类和类的实例定义发出通知的能力,从而将事件和可执行代码捆绑在了一起.事件是对象发送的消息,以发信号通知操作的发生.操作可能是由用户交互引起的,也可能是由某些其他的 ...

  5. C#数字图像处理算法详解大全

    原文:C#数字图像处理算法详解大全 C#数字图像处理算法详解大全 网址http://dongtingyueh.blog.163.com/blog/#m=0 分享一个专业的图像处理网站(微像素),里面有 ...

  6. intellij开发安卓与genymotion配合

    原文:intellij开发安卓与genymotion配合 [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http: ...

  7. 使用Boost的DLL库管理动态链接库

    Boost 1.61新增了一个DLL库,跟Qt中的QLibrary类似,提供了跨平台的动态库链接库加载.调用等功能.http://www.boost.org/users/history/version ...

  8. 10秒完成Linux系统pip在线安装

    对于Python开发攻城狮及系统运维攻城狮来说,pip的安装那是必不可少的一个过程.鉴于网上很多安装过程写得过于复杂,本人根据pip官方手册总结了以下最为快捷的安装方式,只需要2步操作. curl h ...

  9. kafka设计原理(转)

    一.kafka简介 1.1 背景历史 当今社会各种应用系统,诸如商业.社交.搜索.浏览等信息工厂一样不断被生产出各种信息,在大数据时代,我们面临如下几个挑战: 如何收集这些巨大的信息 如何分析它 如何 ...

  10. 如何在 cmd 命令行中查看、修改、删除与添加环境变量

    Windows 和 linux 区别 一.查看所有环境变量的名称和值:Linux下:exportWindows下:set二.根据名称查该环境变量的值:Linux下:echo $环境变量名比如:echo ...