java 第四次实验作业

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

(1)封装

1.一个方法就代表着一个方法的实现。每一个方法都是相互独立的类似与c中的子函数。(对功能的封装)

2.之所以称之为疯传就是对属性来言的私密性,1个就是属性的私有化,2则就是提供的set和get方法,实现私密话的数据提取(对数据的封装)

3.this关键字的使用,总是指向当前的对象,1,this指向当前属性2,this指向当前对象3,this指向当前方法(其中this是默认存在的无论怎么使用,在开发时候一个类的所用属性都活私有化,所以用到set和get使用)。

(2)继承

1.之所以是继承,就是子类继承父类的属性。然而这种这种继承也会有局限性质,就是子类只可以继承父类的(默认的)无参的构造函数,不可以构造有参数的构造函数,如果引用的话就会提示,父类未定义。

2.调用的父类的构造方法必须放在子类的第一行,否则报错。

3.其中this()和super()的区别。
this呢就是调用自身的方法,而且在子类中呢不仅仅可以调用父类的继承的方法,还可以有自己的方法
super则是仅仅可以调用父类继承过来的方法。在java中不支持多继承(一个子类不可以继承多个父类)但是支持多重继承,就是(一个父类可以用拥有多个子类)

(3)多态
多态性是指同名的不同方法在程序中共享,即为同一个方法定义几个版本,运行时根据不同情况执行不同的版本。
一个名字,多个方法
多态性的实现:
覆盖实现多态:(子类重写父类中的方法)
重载实现多态(同一个类中的同名方法)

重写与重载的区别:重写出现在父子之间,重写返回值,方法名,类型都要一样,可以在继承中使用,但是子类约束的权限不能比父类的约束更加苛刻,然而重载必须在一个类中去实现,方法名可以一样,参数的多少和类型有差异

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

package test1;

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

结果当然是不能通过呗,super()的使用方法错了,如果要调用super方法,就必须把super()方法放在第一行,才能使用。修改的结果如上面显示。因为子类在继承父类的方法的基础之上,再加修改。不可以反过来。构造函数(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 Test1{
    public static void main(String args[]) {
    	Animal p=new Dog();
    	Dog animal=(Dog)p;
        animal.shout();
        animal.sleep();
        Dog dog = animal;
        dog.sleep(); 
        Animal dog1=new Animal();
        dog1.shout();
    }
}

结果是错误的,上边的animal他应该是调用的子类的中拥有的属性,所以应该向下转型或者直接构造子类的构造函数两种方法,就可以解决
之后下面的dog1应该是想调用父类的函数,所以两种方法是直接重新构造父类的构造函数或者就是向上转型方法就可以解决了。

4.运行下列程序#

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

以上的程序随机产生的地址信息,而且是加与不加toString方法,就说明,程序在输出的时候总是去尝试去调用对象的toString方法的,然而上面开始的时候并没有tostring方法,也没有输出的语句。

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

因为toString方法是继承系统对象默认里面的,里面有的方法。

Object类具有一个toString()方法,你创建的每个类都会继承该方法。它返回对象的一个String表示,并且对于调试非常有帮助。然而对于默认的toString()方法往往不能满足需求,需要覆盖这个方法。

toString的好处是在碰到“println”之类的输出方法时会自动调用,不用显式打出来。

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

执行结果为

姓名:张三,年龄:20

姓名:张三,年龄:20

说明:返回该对象的字符串表示。通常, toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。

Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:

getClass().getName() + '@' + Integer.toHexString(hashCode())

返回:

该对象的字符串表示形式。

因为它是Object里面已经有了的方法,而所有类都是继承Object,所以“所有对象都有这个方法”。

它通常只是为了方便输出,比如System.out.println(xx),括号里面的“xx”如果不是String类型的话,就自动调用xx的toString()方法

(二)实验总结#

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

类图如下

程序设计思路:首先分别建立Yg、Teat、management类,zy类定义为为父类,之后用语法连接就可以了。

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

类图如下

程序设计思路:使用抽象类建立Boby类还有Plane类当做抽象类和父类,之后分别用Circular,Triangle,Rectangle类去继承抽象类Plane,之后用Ball,Cylinder,Cone类去继承Boby类。按照语法就可以了。

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

类图如下

程序设计思路:
分别建立feerder类,Animal类、Lion类,Monkey类、Pigeon类,在feerder类中构造这三种动物饲养方法,然后这三种动物类继承Animal类,然后运用Test类进行测试。
开始

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

不仅缩短时间,而且更有效率。
第一次的重构为

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

接受之后为

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

还有是用数组接受就是更改成

    	Animal animal[]=new Animal[]{
			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/cg.git

原文地址:https://www.cnblogs.com/chengang4747/p/6719037.html