zoukankan      html  css  js  c++  java
  • Java第四次作业——面向对象高级特性(继承和多态)

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

    (三)代码托管

  • 相关阅读:
    mybatis 错误 Invalid bound statement (not found)
    Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
    bug 记录 Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans
    解决:The Tomcat connector configured to listen on port 8182 failed to start. The port may already be in use or the connector may be misconfigured.
    jquery validate 验证插件 解决多个相同的Name 只验证第一个的方案
    phpStorm+xdebug调试(php7.3)
    小程序视频多个视频播放与暂停
    CSS实现单行、多行文本溢出显示省略号(…)
    Packet for query is too large (4,544,730 > 4,194,304). You can change this value on the server by setting the 'max_allowed_packet' variable.
    idea自动在文件头中添加作者和创建时间
  • 原文地址:https://www.cnblogs.com/chenyameng/p/6727192.html
Copyright © 2011-2022 走看看