代码改变世界

java第四次作业

2017-04-17 20:09  空白格DE  阅读(242)  评论(1)    收藏  举报

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();
    }
}

不能运行,构造函数调用必须调用第一个语句
程序的运行结果:

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

修改后的程序:

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

子类继承了父类的各种属性,构造方法相当于把父类实例化,如果子类实例化的时候不调用父类的构造方法,相当于子类没有父类,也就无法继承,所以不能反过来。

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();
    }
}

(1)、类Animal中没有定义方法sleep()而主方法中调用了 sleep() 方法。应该在Animal中加一个sleep()方法
改为:

 public void sleep() {
            System.out.println("狗狗睡觉......");
        }

(2)、Dog dog = animal;没有把Animals类的对象进行强制转化
改为:

Dog dog =(Dog) animal;

(3)、对Animal类的dog进行声明时应下进行转换
改为:

Animal animal2 = new Dog();       
 dog = (Dog)animal2;

正确结果为:
汪汪......!
狗狗睡觉......
狗狗睡觉......

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()) ; 
  } 
}

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

Person@166afb3
Person@166afb3
以上程序随机输出信息,没有调用String tostring()方法。
(2)那么,程序的运行结果到底是什么呢?利用eclipse打开println(per)方法的源码,查看该方法中又调用了哪些方法,能否解释本例的运行结果?

public void println (Obiect x){
    String s = String valueOf(x);
    synchronized(this){
        print(s);
        newLine();
    }
}

(3)在Person类中添加方法

public String toString(){ 
        return "姓名:" + this.name + ",年龄:" + this.age ; 
 } 

重新运行程序,程序的执行结果是什么?说明什么问题?
结果为:

姓名:张三,年龄:20
姓名:张三,年龄:20
Object类复写了tostring(),导致随机输出信息。

5.其他需要总结的内容。
做实验题的时候学习final关键字的使用方法,知道在使用时需要注意一下几点:
1、使用final声明的类不能有子类。
2、使用final声明的方法不能被子类所覆写。
3、使用final声明的变量即成为常量,常量不可以修改。
抽象类的使用:
1、包含一个抽象方法的类必须是抽象类。
2、抽象类和抽象方法都要使用abstract关键字声明。
3、抽象方法只需声明而不需要实现
4、抽象类必须被子类继承,子类(如果不是抽象类)必须覆写抽象类中的全部抽象方法。

这次的实验内容相对前几次的实验题比较简单,所以我这次做的比之前顺利点,前两个题看着书上的例题一点一点学习的,第三个实验题是涉及到重构的,重构的方法还是不太理解,所以我认为写的程序不是特别好,在私下我还是多看看书,在课上做笔记,争取把落下的知识补回来。

(二)实验总结

实验内容:

1、定义员工类,具有姓名、年龄、性别属性,并具有构造方法和显示数据方法。定义管理层类,继承员工类,有自己的属性职务和年薪。定义职员类,继承员工类,并有自己的属性所属部门和月薪。定义一个测试类,进行测试。画出类图。
程序设计思路:先定义父类员工,在实例化管理类和职工类时先调用了抽象类的构造方法,将姓名,年龄,性别进行设置,然后在输出信息
问题:没有调用父类中的参数的构造方法
解决:在勒种添加super()调用父类中三个参数的构造方法。

class guanli extends yuangong{
	private String zhiwu;
	private String nianxin;
	public guanli(String name, String age, String sex,String zhiwu,String nianxin) {
		super(name, age, sex);
		this.setZhiwu(zhiwu);
		this.setNianxin(nianxin);
	}
	public String getZhiwu() {
		return zhiwu;
	}
	public void setZhiwu(String zhiwu) {
		this.zhiwu = zhiwu;
	}
	public String getNianxin() {
		return nianxin;
	}
	public void setNianxin(String nianxin) {
		this.nianxin = nianxin;
	}

2、按照下面要求完成类的设计
(1)设计一个平面图形抽象类(提供求该类对象周长和面积的方法)和一个立体图形抽象类(提供求该类对象表面积和体积的方法)
(2)设计球类、圆柱类,圆锥类、矩形类、三角形类、圆类,分别继承平面图形抽象类和立体图形抽象类。
(3)建立测试类,进行测试。画出类图。
设计思路:
设计平面抽象类,再创建矩形类,圆类,三角类,让这三个类继承平面类中的属性。
设计立体抽象类,在创建球类,圆柱类,锥类,让这三个类继承立体抽象类中的属性


3、 参考类图,重构下面的实例,分析和理解多态的含义和用途
(1)某动物园有一饲养员小李,每天需要给他所负责饲养的一只狮子、五只猴子和十只鸽子喂食。 请用一个程序来模拟他喂食的过程。

分析这种编程方式有什么不合理的地方。
(2)第一次重构,引入继承,利用抽象类和对象多态重构程序,Animal类采用抽象类, 合并Feeder类中的方法

分析程序是否还可以进一步优化
(3)第二次重构,修改feedAnimals方法,让它接收一个Animal数组

Animal an[]={                            new Lion(),
	 				new Monkey(),
	 				new Monkey(),
	 				new Monkey(),
	 				new Monkey(),
	 				new Monkey(),
	 				new Pigeon(),
	 				new Pigeon(),
	 				new Pigeon(),
	 				new Pigeon(),
	 				new Pigeon(),
	 				new Pigeon(),
	 				new Pigeon(),
	 				new Pigeon(),
	 				new Pigeon(),
	 				new Pigeon()
	 		 	
	 		    };

通过本题的重构,说一下多态有什么好处。在第二次重构之后,是否就能应对各种场景了呢?你认为还应该做哪些优化?
多态的好处:把不同的子类对象都当做父类看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编写,以适应不同的需求。
代码托管:https://git.oschina.net/hebau_cs15/si.git

不能应对各种场景。