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

不能通过编译 构造函数的调用必须是构造函数中的第一个语句,子类的构造方法必须先调用父类构造,再执行子类构造

修改后的程序:

class Parent extends Grandparent {
	public Parent() {         
    	super("Hello.Grandparent.");
    	System.out.println("Parent 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();
	}
}

错误1:

向上转型。sleep()方法是在子类中新定义的,想要在父类声明的变量中调用需要在父类中也添加一个sleep()用来实现方法的覆写。

错误2:

向下转型。通过(Dog)animal将父类转为子类即可

修改后的程序:

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

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

Person@166afb3
Person@166afb3

说明即使per没有成功调用tostring方法,但是也输出了类名和地址信息

(2)那么,程序的运行结果到底是什么呢?利用eclipse打开println(per)方法的源码,查看该方法中又调用了哪些方法,能否解释本例的运行结果?

源代码:

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

(3)在Person类中增加如下方法:

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

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

运行结果:

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

说明了,子类Person类覆写了Object类中toString()方法

(二)实验总结

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

工具:ProcessOn

参考资料:UML 类图

程序设计思路:
定义员工类为父类,管理层和职员类为员工类的子类。父类属性为姓名、性别、年龄。管理层属性为职务、年薪。职员类属性为所属部门、月薪。定义测试类,输出所有员工的信息。

实验问题分析:

问题:管理层和职员信息只有本类的属性

原因:tell方法中没有添加父类的属性

解决方案:

public void tell(){
    System.out.println("员工的姓名:"+name+" 年龄:"+age+"性别:"+sex+" 经理的职务:"+work+" 年薪:"+yearmoney);
}

类图:

2.图形工具

(1)设计一个平面图形抽象类(提供求该类对象周长和面积的方法)和一个立体图形抽象类(提供求该类对象表面积和体积的方法)

(2)设计球类、圆柱类,圆锥类、矩形类、三角形类、圆类,分别继承平面图形抽象类和立体图形抽象类。

(3)建立测试类,进行测试。画出类图。

类图:

(三)代码托管

地址:

http://git.oschina.net/hebau_cs15/hebau-cs02cmy

posted on 2017-04-18 13:09  绝版de初夏  阅读(262)  评论(0编辑  收藏  举报