java第四次作业

计科1501 张鹏


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

此程序不能运行。
因为构造函数调用必须是构造函数中的第一个语句
此程序应改为:

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 test1{
    public static void main(String args[]) {
        Child c = new Child();
    }
}

此程序的运行结果为:

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

构造函数(constructor)是一种特殊的方法。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们即构造函数的重载。构造函数的功能主要用于在类 的对象创建时定义初始化的状态。
构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。
子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。
不能反过来调用也是这个原因,因为父类根本不知道子类有神魔变量而且这样一来子类也得不到初始化的父类变量,导致程序运行出错!


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

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

class Animal{
  void shout(){
      System.out.println("动物叫!");
  }
  void sleep(){
      System.out.println("动物睡!");
  }
}

(二)、类型不匹配:不能从 Animal转换为Dog,应使用强制类型转换, 应改为:

Dog dog =(Dog) animal;

(三)、Animal animal2 = new Animal(); 父类引用的对象是父类本身,在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException错误。
dog = (Dog)animal2;
应改为:

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

**综上所述,正确的程序为:

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

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

说明了:System.out.println(per); per无论有没有调用toString()方法,都输出了类名和地址信息,都会调用object中toString()方法
System.out.println(per.toString()) ;
(3)在Person类中增加如下方法

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

运行结果为:

姓名:张三,年龄:20
姓名:张三,年龄:20

说明什么问题?
由此说明了“子类Person类覆写了Object类中toString()方法”。

(二)实验总结

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

程序设计思路:首先分别建立Yuangong、Guanli、Zhiyuan类,Yuangong类定义为为父类,然后Guanli类与Zhiyuan类继承Yuangong类,然后再实例化三类,运用switch进行查找与输出。


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

类图如下:

程序设计思路:使用抽象类分别建立Pingchou与Lichou类,分别让yuan类、Juxing类、Sanjiao类与Qiu类、Yuanzhu类、Yuanzhui类继承,然后再运用switch判断所求图形为哪种类型,再分别输入相应的边长,然后进行输出。
3. 参考类图,重构下面的实例,分析和理解多态的含义和用途
(1)某动物园有一饲养员小李,每天需要给他所负责饲养的一只狮子、五只猴子和十只鸽子喂食。 请用一个程序来模拟他喂食的过程。


程序设计思路:
分别建立feerder类,Animal类、Lion类,Monkey类、Pigeon类,在feerder类中构造这三种动物饲养方法,然后这三种动物类继承Animal类,然后运用test类进行测试。
(2)、第一次重构,引入继承,利用抽象类和对象多态重构程序,Animal类采用抽象类, 合并Feeder类中的方法

程序中三种动物都为Animal类,所以可以把此段程序:

public void feedlion(Lion lion){
		lion.eat();
	}
	public void feedMonkey(Monkey monkey){
		monkey.eat();
	}
	public void feedPigeon(Pigeon pigeon){
		pigeon.eat();
	}

改为:

public void feedanimal(Animal animal){
		animal.eat();
	}	

更加简洁。
3、第二次重构,修改feedAnimals方法,让它接收一个Animal数组

第一次重构后为:

public void feedanimal(Animal animal){
		animal.eat();
	}	

接收一个数组后为:

public void feedAnimal(Animal[] animal){
		for(Animal an : animal){
		     an.eat();
	    }	

(三)代码托管

posted on 2017-04-15 16:44  雯水声  阅读(355)  评论(0编辑  收藏  举报