java实验五(继承与多态)

一、 实验目的及要求

  1. 设计一个数据类型判断类Polymorphism,使用重载、装箱等技术判断一个不带等号的Java表达式的结果的数据类型。
  2. 设计一个链表结点类LinkNode,此类可以存放int、long、float、double、byte、short、String、StringBuffer类型的数据。用此类:a、随机产生100个整数(范围自定)的链表,在生成的过程中从小到大排列,然后输出;b、随机产生100个6个英文字母的单词的链表,在生成的过程中从小到大排列,然后输出。(关注装箱和拆箱相关概念
    Integer String)
  3. A、在main()中使用上题的LinkNode类创建4个实例,并赋予不同的值(long、double、
    StringBuffer、MyDate),然后使用Object中默认的toString()方法(从超级父类继承而来) 显示结果。
    B、继承LinkNode类创建新类LinkNodeS,在其中重写Object中默认的toString()方法(将结点的value转换成对应的字符串),main()中用LinkNodeS类同样创建4个实例,并赋予和上面同样的值(long、double、StringBuffer、MyDate),观察使用新的toString()方法的效果,体会继承与多态。(MyDate的日期toString用标准格式)
  4. 有来自4个类别(鸟类、昆虫类、爬行类和鱼类)的100个动物聚在一起开会,商议和另一个动物部落打仗事宜,会议要求每个动物都要报告自己所属的动物类别和自己的天赋,以便选拔人才、组织兵力出战。
    设计:用Animal作为基类,鸟类、昆虫类、爬行类和鱼类各作为Animal的子类设计类层次结构,设计时运用继承、重写并设计多态机制,同时对每个子类至少要添加一个其描述的动物特有的行为和一个特有的属性,以更准确地描述子类对象。
    使用:用循环随机生成这100个动物装入动物数组,要对每个动物进行编号和随机命名,用循环让每个参会的动物报告自己的类别和天赋。

二、实验设备(环境)
三、实验内容与步骤

  1. Poly类
public class JudgeType 
{
	public static void main(String[] args) 
	{
		// TODO Auto-generated method stub
		Polymorphism poly=new Polymorphism();
		System.out.println(poly.getType(1));
		System.out.println(poly.getType(9.9));
		System.out.println(poly.getType(true));
		System.out.println(poly.getType(poly));
	}
}

class Polymorphism
{
	private final static String INT_TYPE = "int";
    private final static String LONG_TYPE = "long";
    private final static String DOUBLE_TYPE = "double";
    private final static String FLOAT_TYPE = "float";
    private final static String CHAR_TYPE = "char";
    private final static String BYTE_TYPE = "byte";
    private final static String SHORT_TYPE = "short";
    private final static String BOOLAEN_TYPE = "boolean";
 
    public static String getType(int i) {
		return INT_TYPE;
	}
    public static String getType(long l) {
        return LONG_TYPE;
    }
    public static String getType(double d) {
        return DOUBLE_TYPE;
    }
    public static String getType(float f) {
        return FLOAT_TYPE;
    }
    public static String getType(char c) {
        return CHAR_TYPE;
    }
    public static String getType(byte by) {
        return BYTE_TYPE;
    }
    public static String getType(short s) {
        return SHORT_TYPE;
    }
    public static String getType(boolean bo) {
        return BOOLAEN_TYPE;
    }
    public static String getType(Object obj){//超级父类Object,所有类型的变量都可装箱
        return obj != null ? obj.toString().split("@")[0] : null;//obj不为空时,转为String型并拆分返回数组,实现返回其类型;若为空,则返回null
    }
}
  1. 链表排序
public class UseLinkNode 
{
	public static void main(String[] args) 
	{
		// TODO Auto-generated method stub
		intLink(100,1000);
		letterLink(100);
	}

	
	public static void intLink(int count,int range)
	{
		LinkNode firstNode=new LinkNode(0);
		LinkNode lastNode=new LinkNode(1000);
		LinkNode current;
		LinkNode before;
		
		for(int i=0;i<count;i++)
		{
			current=firstNode;
			before=firstNode;
			LinkNode random=new LinkNode((int)(Math.random()*(range+1)));
			if(i==0)
			{
				firstNode.nextNode=random;
				random.nextNode=lastNode;
				continue;
			}
			current=current.nextNode;
			while((Integer)random.data>(Integer)current.data)
			{
				current=current.nextNode;
				before=before.nextNode;
			}
			before.nextNode=random;//成功查找出random的插入位置,在before与current之间
			random.nextNode=current;
		}
		
		current=firstNode.nextNode;
		for(int i=0;i<count;i++)
		{
			current.display();
			current=current.nextNode;
			if((i+1)%10==0)
			{
				System.out.println();
			}
		}
	}
	
	public static void letterLink(int count)
	{
		LinkNode firstNode=new LinkNode("aaaaaa");
		LinkNode lastNode=new LinkNode("zzzzzz");
		LinkNode current;
		LinkNode before;
		
		for(int i=0;i<count;i++)
		{
			current=firstNode;
			before=firstNode;
			
			StringBuffer data=new StringBuffer();
			for(int j=0;j<6;j++)
			{
				int num=(int)(Math.random()*26);
				data.append((char)('a'+num));
			}
			LinkNode random=new LinkNode(data);
			if(i==0)
			{
				firstNode.nextNode=random;
				random.nextNode=lastNode;
				continue;
			}
			current=current.nextNode;
			while(random.data.toString().compareTo(current.data.toString())>0)
			{
				current=current.nextNode;
				before=before.nextNode;
			}
			before.nextNode=random;
			random.nextNode=current;
		}
		
		current=firstNode.nextNode;
		for(int i=0;i<count;i++)
		{
			System.out.print(current.data+" ");
			current=current.nextNode;
			if((i+1)%10==0)
			{
				System.out.println();
			}
		}
	}
}


class LinkNode
{
	Object data;
	LinkNode nextNode;

	
	LinkNode(Object obj)
	{
		data=obj;
		nextNode=null;
	}
	
	public void display()
	{
		System.out.print(data.toString()+" ");
		for(int i=0;i<3-data.toString().length();i++)
		{
			System.out.print(" ");
		}
	}
}
  1. 链表继承改写
import java.text.SimpleDateFormat;

public class UseLinkNode2 
{
	public static void main(String[] args) 
	{
		// TODO Auto-generated method stub
		long myLongData=100;
		double myDoubleData=100.0;
		StringBuffer myStringBufferData=new StringBuffer("student");
		MyDate myDateData=new MyDate();
		
		LinkNode myLong1=new LinkNode(myLongData);
		LinkNode myDouble1=new LinkNode(myDoubleData);
		LinkNode myStringBuffer1=new LinkNode(myStringBufferData);
		LinkNode myDate1=new LinkNode(myDateData);
		
		System.out.println(myLong1.toString());
		System.out.println(myDouble1.toString());
		System.out.println(myStringBuffer1.toString());
		System.out.println(myDate1.toString());
		
		LinkNodeS myLong2=new LinkNodeS(myLongData);
		LinkNodeS myDouble2=new LinkNodeS(myDoubleData);
		LinkNodeS myStringBuffer2=new LinkNodeS(myStringBufferData);
		LinkNodeS myDate2=new LinkNodeS(myDateData);
		
		System.out.println(myLong2.toString());
		System.out.println(myDouble2.toString());
		System.out.println(myStringBuffer2.toString());
		System.out.println(myDate2.toString());
	}
}

class LinkNode
{
	Object data;
	LinkNode nextNode;
	
	LinkNode(Object obj)
	{
		data=obj;
		nextNode=null;
	}
}

class LinkNodeS extends LinkNode
{
	LinkNodeS(Object obj)
	{
		super(obj);
	}
	
	public String toString()
	{
		return data.toString();
	}
}

class MyDate
{
	private String date;
	
	//不带参数的构造方法,取当前系统时间
	public MyDate()
	{
		SimpleDateFormat myDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		java.util.Date  date0=new java.util.Date();
		date=myDateFormat.format(date0);
	}
	
	public String toString()
	{
		return date.toString();
	}
}
  1. Animal类(法1)
public class AnimalMeeting 
{
	public static void main(String[] args) 
	{
		Animal[] animalArray=new Animal[100];
		
		for(int j=0;j<100;j++)
		{
			StringBuffer name=new StringBuffer();
			for(int i=0;i<5;i++)
			{
				int word=(int)(Math.random()*26);//word为0到25之间的随机数
				name.append((char)(word+'a'));//在a到z之间随机生成一个字母加到name上,得到一个五位字符串的name
			}
			int type=(int)(Math.random()*4);
			switch(type)
			{
				case 0:
					animalArray[j]=new Bird(j,name);
					break;
				case 1:
					animalArray[j]=new Insect(j,name);
					break;
				case 2:
					animalArray[j]=new Reptile(j,name);
					break;
				case 3:
					animalArray[j]=new Fish(j,name);
					break;
			}
			animalArray[j].showType();
			animalArray[j].showTalent();
		}
		// TODO Auto-generated method stub
	}
}

class Animal
{
	public int id;//编号
	public String name;//名字
	public String type;//类别:鸟类、昆虫类、爬行类和鱼类之一

	public void showType()//在meeting上秀自己的类别
	{
		System.out.println("My ID is "+id+" and I am just an animal, my type is going to be determined later.");
	}
	
	public void showTalent()//在meeting上秀自己的天赋特长
	{
		System.out.println("I don’t know what I am talented at right now.");
	}
}

class Bird extends Animal
{
	public String talent;
	
	Bird(int id,StringBuffer name)
	{
		this.id=id;
		this.name=name.toString();
		type="bird";
		talent="fly";
	}
	
	public void showType()
	{
		System.out.println("My ID is "+id+",my name is "+name+" and my type is "+type+".");
	}
	
	public void showTalent()//在meeting上秀自己的天赋特长
	{
		System.out.println("My talent is "+talent);
	}
}

class Insect extends Animal
{
	public String talent;
	
	Insect(int id,StringBuffer name)
	{
		this.id=id;
		this.name=name.toString();
		type="insect";
		talent="small";
	}
	
	public void showType()
	{
		System.out.println("My ID is "+id+",my name is "+name+" and my type is "+type+".");
	}
	
	public void showTalent()//在meeting上秀自己的天赋特长
	{
		System.out.println("My talent is "+talent);
	}
}

class Reptile extends Animal
{
	public String talent;
	
	Reptile(int id,StringBuffer name)
	{
		this.id=id;
		this.name=name.toString();
		type="reptile";
		talent="quick";
	}
	
	public void showType()
	{
		System.out.println("My ID is "+id+",my name is "+name+" and my type is "+type+".");
	}
	
	public void showTalent()//在meeting上秀自己的天赋特长
	{
		System.out.println("My talent is "+talent);
	}
}

class Fish extends Animal
{
	public String talent;
	
	Fish(int id,StringBuffer name)
	{
		this.id=id;
		this.name=name.toString();
		type="fish";
		talent="swim";
	}
	
	public void showType()
	{
		System.out.println("My ID is "+id+",my name is "+name+" and my type is "+type+".");
	}
	
	public void showTalent()//在meeting上秀自己的天赋特长
	{
		System.out.println("My talent is "+talent);
	}
}

4.Animal类(法2:抽象类)

abstract class Animal//创建抽象类型的Animal
{
	public int id;//编号
	public String name;//名字
	public String type;//类别:鸟类、昆虫类、爬行类和鱼类之一

	abstract void showType();
	abstract void showTalent();
}

4.Animal类(法3:接口)

public class AnimalMeeting 
{
	public static void main(String[] args) 
	{
		ShowSomething[] animalArray=new ShowSomething[100];
		
		for(int j=0;j<100;j++)
		{
			StringBuffer name=new StringBuffer();
			for(int i=0;i<5;i++)
			{
				int word=(int)(Math.random()*26);//word为0到25之间的随机数
				name.append((char)(word+'a'));//在a到z之间随机生成一个字母加到name上,得到一个五位字符串的name
			}
			int type=(int)(Math.random()*4);
			switch(type)
			{
				case 0:
					animalArray[j]=new Bird(j,name);
					break;
				case 1:
					animalArray[j]=new Insect(j,name);
					break;
				case 2:
					animalArray[j]=new Reptile(j,name);
					break;
				case 3:
					animalArray[j]=new Fish(j,name);
					break;
			}
			animalArray[j].showType();
			animalArray[j].showTalent();
		}
		// TODO Auto-generated method stub
	}
}

interface ShowSomething
{
	public void showType();
	public void showTalent();
}

class Bird implements ShowSomething
{
	public int id;
	public String name;
	public String type;
	public String talent;
	
	Bird(int id,StringBuffer name)
	{
		this.id=id;
		this.name=name.toString();
		type="bird";
		talent="fly";
	}
	
	public void showType()
	{
		System.out.println("My ID is "+id+",my name is "+name+" and my type is "+type+".");
	}
	
	public void showTalent()//在meeting上秀自己的天赋特长
	{
		System.out.println("My talent is "+talent);
	}
}

class Insect implements ShowSomething
{
	public int id;
	public String name;
	public String type;
	public String talent;
	
	Insect(int id,StringBuffer name)
	{
		this.id=id;
		this.name=name.toString();
		type="insect";
		talent="small";
	}
	
	public void showType()
	{
		System.out.println("My ID is "+id+",my name is "+name+" and my type is "+type+".");
	}
	
	public void showTalent()//在meeting上秀自己的天赋特长
	{
		System.out.println("My talent is "+talent);
	}
}

class Reptile implements ShowSomething
{
	public int id;
	public String name;
	public String type;
	public String talent;
	
	Reptile(int id,StringBuffer name)
	{
		this.id=id;
		this.name=name.toString();
		type="reptile";
		talent="quick";
	}
	
	public void showType()
	{
		System.out.println("My ID is "+id+",my name is "+name+" and my type is "+type+".");
	}
	
	public void showTalent()//在meeting上秀自己的天赋特长
	{
		System.out.println("My talent is "+talent);
	}
}

class Fish implements ShowSomething
{
	public int id;
	public String name;
	public String type;
	public String talent;
	
	Fish(int id,StringBuffer name)
	{
		this.id=id;
		this.name=name.toString();
		type="fish";
		talent="swim";
	}
	
	public void showType()
	{
		System.out.println("My ID is "+id+",my name is "+name+" and my type is "+type+".");
	}
	
	public void showTalent()//在meeting上秀自己的天赋特长
	{
		System.out.println("My talent is "+talent);
	}
}

四、实验结果与数据处理

  1. Poly类
    int
    double
    boolean
    Polymorphism

  2. 链表排序
    1 6 11 26 31 37 40 57 60 60
    84 97 100 108 126 129 129 150 161 171
    179 182 185 194 196 204 207 209 216 221
    239 247 255 255 268 293 302 324 324 326
    360 365 434 434 445 445 453 453 461 471
    473 474 487 488 488 509 536 567 570 580
    583 584 586 589 605 606 631 670 721 725
    730 736 739 748 757 760 763 777 778 780
    796 812 823 843 878 890 908 909 912 913
    917 925 945 945 949 952 952 955 960 967
    acvvzx afyugf agckxh ajgilk aoolus arysoj ashwya asxpsd awdqvd bhhkww
    bnqbre bnspcp bpcoik bpuotq btzzjq bxrgdc cbyqxj cfjjpj cogaul cozbpl
    cpvtrx dfptuu difmzd diuumy dodwot dyshjx ecuhhl edviyl efcljs eimoua
    eoourl fbarze fcksbi fgiztd fkxicw fttbww gffkps gogtfu grchaz grltok
    gurfij hejcdg hixuch hmrinw hrjjig ikbvij iktuea isprbp jdwsop jflcek
    jipzfb jyfitp kciadl kfqtqd khhikm kihqsn kjuwlf kldrap mmisjd mobofn
    mpdcxi mreeii ndxpih nedegt ngqduo nqhius oifeil oixhlh ojcwmf omtfnn
    pkkuwy pndsxm pnmhja qofvmd rdmxkm rfozay rhewat rhhlnz rpagob rzxvef
    slnnah svttsq thkwjl tkmvtg twphdz ucreuc ulgjog uyaozy vuqmtx wadjfx
    whpbtk wknyqm wxhlmo xbqlre xzkjic ybxhtq yrzqic yutcnn zhyyra zxlbtx

  3. 链表继承改写
    LinkNode@4554617c
    LinkNode@74a14482
    LinkNode@1540e19d
    LinkNode@677327b6
    100
    100.0
    student
    20201120203810

  4. 4.Animal类
    My ID is 0,my name is uwdpj and my type is bird.
    My talent is fly
    My ID is 1,my name is flvjj and my type is fish.
    My talent is swim
    My ID is 2,my name is jahet and my type is fish.
    My talent is swim
    My ID is 3,my name is qydnb and my type is reptile.
    My talent is quick
    下省略

五、分析与讨论(体会、感想、意见、建议)

  1. Poly类
    在本次实验中,我深刻体会到了重载与装箱带来的好处。一模一样的方法名,却由于参数类型的不同,使得程序运行时有选择性地进行调用,从而巧妙地实现了判断数据类型的目的。同时,还体会到了超级父类Object的运用,即可以装进任何的子类实例,使得代码书写更方便,同时适用范围也大大提升。
  2. 链表排序
    在本次实验中,我体会到了使用Object类的好处。在本次实验中一共构造了两种类型的链表,整型的和字符串型的,然而却只用构造一个链表结点类,就是因为有超级父类的存在,使得任何类型的数据都能放到结点中,从而大大减少了本次实验的书写量。
  3. 链表继承改写
    在本次实验中,我对子类改写父类方法的运用有了更深入的认识。在本题的父类LinkNode中并没有写toString()方法,于是在main函数中使用时将会自动调用object中默认的toString()方法,也就是输出来“类名+哈希编码”;在子类LinkNodeS中我们重写了toString()方法,于是把相同的值装进子类后,将会调用子类版本的toString()方法,从而输出来我们想要的数值。
  4. Animal类(法1)
    在本次实验中,我深刻体会到了继承与多态带来的便利。就比如animalArray[j].showType();animalArray[j].showTalent();这两个语句,看似一模一样,但由于我们把子类实例装进了父类变量,同时对子类进行了重写,于是根据子类实例的不同,看似一模一样的方法却可以执行任何子类改写过的版本,大大减轻了代码的书写量;子类的继承也带来了极大的便利,每种动物都拥有的id,name,type可以直接从父类处继承下来,子类自己只需要添加各自的talent即可。
    4.Animal类(法2:抽象类)
    通过本次实验,我对抽象类的运用有了更深入的了解。在法1中,父类Animal中的两个方法并没有实际的使用起来,而只是为了重载而不得不写上方法体,而学会了抽象类就能很好地解决这个问题。在Animal类中不需要给出这两个方法的具体实现,而是在它的四个子类中提供自己的实现,使得设计更加清晰,效率更高。
    4.Animal类(法3:接口)
    通过本次实验,我对接口的运用有了更深入的了解。既然Bird,Insect,Reptile,Fish都必须实现showType与showTalent两个方法,那就可以直接在接口中写上这两个方法,然后在四个类中去实现该接口,注意接口中只进行方法的声明,而不提供方法的实现。

继承

  • 子类不能继承父类的所有成员,带private的属性、方法不能继承;
    构造方法不能被继承,但是可以通过super调用父类的构造方法
  • Java中只支持单继承,即只能从一个类继承,extends后的类名只能有一个(Java中是通过接口实现多重继承的)
  • super指向所在类的父类,用来引用父类的成员变量和方法

注意:在类本身中调用构造方法用this,调用父类的构造方法用super

class Animal
{
	public int id;
	public String name;
	public String type;
	
	Animal(int id,String name)
	{
		this.id=id;
		this.name=name;
	}
}
class Bird extends Animal
{
	public String talent;
	
	Bird(int id,String name)
	{
		super(id,name);//调用父类的构造方法
		type="Bird";
		talent="Fly";
	}
}

子类对象的创建与初始化

  1. 分配对象所需要的全部内存空间,并初始化为0/false/null值;
  2. 按继承关系,自顶向下显示初始化
  3. 按继承关系,自顶向下调用构造方法

具体实现如下:1.分配成员变量的存储空间并进行默认的初始化;2.绑定构造方法参数,就是new Person(实际参数列表)中所传递进的参数赋值给构造方法中的形式参数变量;3.显式或隐式追溯调用父类的构造方法(一直到Object类为止,Object是所有Java类的最顶层父类),父类的构造方法又从步骤(2)开始对父类执行这些流程,父类的构造方法的执行流程结束后,回到当前构造方法,当前构造方法继续往下执行;4.进行实例变量的显示初始化操作,也就是执行在定义成员变量时就对其进行赋值的语句;5.执行当前构造方法的方法体中的程序代码
即表现为自下向上调用,自顶向下完成实例化


多态三条件:

  1. 存在父类、子类
  2. 子类对父类的方法进行了重写
  3. 子类实例装进父类变量(上溯造型)

通过一个父类变量发出的方法调用,可能执行的是该方法在父类中的实现,也可能是在某个子类中的实现,这只能在运行时刻根据该变量指向的具体对象类型确定,本质就是对外一个接口,内部多种实现


抽象
抽象方法:没有方法体的方法
抽象类:有一个或多个抽象方法
抽象类不能创建实例,可以用子类继承实现抽象方法,然后创建子类的实例,以此实现多态机制


接口
强制实现类,满足接口的功能需求。
接口中定义的常量具有默认属性:public,final,static
接口中定义的方法默认具有:pubilc,abstract

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值