实验2 类的继承性
一、实验目的
掌握面向对象的继承性在Java中的实现方法;掌握super关键字的用法,体会抽象类和抽象方法的作用。
二、实验内容
1.程序理解:
1)类的继承
2)第4章课后编程第1题
class Student {
public String name;
public int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
public void show(){
System.out.println("name: "+name+" age: "+age);
}
}
class UnderGraduate extends Student{
public String degree;
public UnderGraduate(String name,int age,String degree){
super(name, age);
this.degree=degree;
}
public void show(){
System.out.println("name: "+name+" age: "+age+" degree: "+degree);
}
}
public class Test01{
public static void main(String[] args) {
Student student = new Student("zhangsan", 16);
student.show();
UnderGraduate underGraduate = new UnderGraduate("lisi", 20, "bechalor");
underGraduate.show();
}
2.编程题:
(1)请按照以下要求设计类。( 程序1)
要求如下:
1)设计Animal类。类中定义一个成员变量animalName,表示动物的名称,变量animalName是String类型,默认初始值。在该类中再定义一个成员方法shout(),表示动物发出叫声的行为,该方法能输出名称为animalName的动物发出叫声,例如输出“波斯猫发出叫声”。
2)设计Cat类。使用关键字extends继承Animal类。Cat类中定义一个public类型的构造方法,该构造方法拥有一个String类型的参数catName,通过该参数,为Cat类中继承自Animal类的animalName成员变量赋值。
3)设计一个测试类。类名为ExtendsTest,在main方法中定义一个 String类型的name变量,并为它赋值为”波斯猫”,然后使用有参构造创建Cat类的对象,并使用对象的引用变量调用shout()方法。
(2)设计父类和一个子类,在子类里面通过super关键字去调用父类的成员变量和成员方法,在子类的构造方法中使用super关键字调用父类的构造方法,在测试类里进行验证。(程序2)
(3)创建平面图形抽象类(PlaneGraphic)及其子类三角形(Triangle), 圆(Circle),长方形(Rectangle)的一个继承分级结构。在抽象类PlaneGraphic中,提供计算图形周长和面积的抽象方法,并在各子类中实现抽象方法,从而根据不同类型的平面图形计算相应的周长和面积。提示:三角形面积计算用海伦公式:,p为三角形的半周长。(程序3)
(4)请按照以下要求设计一个Outer类。(程序4)
要求如下:
1)定义一个外部类Outer,并在该类中定义一个静态内部类Inner。
2)在内部类中定义一个静态变量staticField和一个静态方法staticMethod(),并将该变量的值设置为”静态内部类的静态变量”,该方法中输出”静态内部类的静态方法”。
3)定义一个测试类,在main()方法中输出staticField的值,并且调用静态方法staticMethod()。
(5)熟悉Eclipse开发工具。
请自己学习课本第11章,熟悉使用Eclipse进行程序调试(418页),了解jar文件的导入和导出(422页)。
三、实验结果和分析
说明:请截图给出各个程序的运行结果,并做必要的分析。
(1)程序1运行结果
分析:Cat类通过extends关键字继承了Animal类,这样Cat类便是Animal类的子类。从运行结果不难看出,子类虽然没有定义animalName属性和shout()方法,但是却能访问这两个成员,这就说明,子类在继承父类的时候,会自动拥有父类的所有成员,Cat类定义了有参构造函数,在测试类的main方法中使用有参构造创建Cat类对象,运行结果如图所示
(2)程序2运行结果
分析:定义了一个Child类继承Father类,并重写了Father类的eat()方法,在子类Child的eat()方法中使用”super.eat()”调用了父类被重写的方法,在introFather()方法中使用“super.age”访问父类的成员变量。从运行结果可以看出,子类通过super关键字成功地访问父类的成员变量和成员方法。在实例化Child对象时一定会调用Child类的构造方法,从运行结果可以看出,Child类的构造方法被调用时,父类的构造方法也被调用了。
(3)程序3运行结果
分析:从运行结果可以看出,子类实现了父类的抽象对象后,可以正常进行实例化,并通过实例化对象调用方法。抽象类其实是约束子类的方法命名,在抽象父类中定义抽象方法,在子类中实现,不同的参数通过成员变量实现。
(4)程序4运行结果
分析:内部类Inner使用static关键字来修饰,是一个静态内部类,实例化方式与非静态的成员内部类的实例化方式不一样,在静态内部类中科院定义静态的成员,而在非静态的内部类中不允许定义静态的成员。
四、实验源代码
说明:请将各程序的源代码复制粘贴到这里。
(1)程序1源代码
//定义Animal类
class Animal{
String animalName;
//定义动物叫的方法
void shout(){
System.out.println(animalName+"发出叫声");
}
}
//定义Cat类继承Animal类
class Cat extends Animal{
//类中定义一个public类型的构造方法
public Cat(String catName){
animalName=catName;
}
}
//定义测试类
public class ExtendsTest {
public static void main(String[] args) {
String name="波斯猫"; //定义一个 String类型的name变量,并为它赋值为”波斯猫”,
Cat cat=new Cat(name); //使用有参构造创建Cat类的对象
cat.shout(); //使用对象的引用变量调用shout()方法。
}
}
(2)程序2源代码
//定义Father类
class Father{
int age=30;
String food="小熊饼干";
//定义Father类有参构造函数
public Father(String name){
System.out.println("我的名字叫"+name);
}
//定义喜欢吃的方法
void eat(){
System.out.println("我喜欢吃"+food);
}
}
//定义Child类
class Child extends Father{
//在子类的构造方法中使用super关键字调用父类的构造方法,
public Child(){
super("蜡笔小新");
}
//在子类里面通过super关键字去调用父类的成员方法,
void eat(){
super.eat();
}
//在子类里面通过super关键字去调用父类的成员变量
void introFather(){
System.out.println("我爸爸今年"+age+"岁了");
}
}
//定义测试类
public class Example2 {
public static void main(String[] args) {
Child child=new Child(); //创建一个Child类的实例对象
child.eat(); //调用Child类的eat方法
child.introFather(); //调用Child类的introFather方法
}
}
(3)程序3源代码
import java.util.Scanner;
//定义抽象类PlaneGraphic
abstract class PlaneGraphic{
double area;
//定义抽象方法getArea
abstract void getArea();
}
//定义Triangle类继承抽象类PlaneGraphic
class Triangle extends PlaneGraphic{
double a,b,c;
//定义Triangle类有参构造函数
public Triangle(double a,double b,double c){
this.a=a;
this.b=b;
this.c=c;
}
//实现抽象方法getArea()
void getArea(){
double p=(a+b+c)/2;
double area=Math.sqrt(p*(p-a)*(p-b)*(p-c));
System.out.println("该三角形的面积是:"+area);
}
}
//定义Circle类继承抽象类PlaneGraphic
class Circle extends PlaneGraphic{
double r;
//定义Circle类有参构造函数
public Circle(double r){
this.r=r;
}
//实现抽象方法getArea()
void getArea(){
double area=Math.PI*r*r;
System.out.println("该圆的面积是:"+area);
}
}
//定义Rectangle类继承抽象类PlaneGraphic
class Rectangle extends PlaneGraphic{
double x,y;
//定义Rectangle类有参构造函数
public Rectangle(double x,double y){
this.x=x;
this.y=y;
}
//实现抽象方法getArea()
void getArea(){
double area=x*y;
System.out.println("该矩形的面积是:"+area);
}
}
//定义测试类
public class Example3 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入三角形的边长:");
double a1=sc.nextDouble();
double b1=sc.nextDouble();
double c1=sc.nextDouble();
Triangle t=new Triangle(a1,b1,c1);//实例化Triangle对象
t.getArea();
System.out.println("请输入圆的半径:");
double r1=sc.nextDouble();
Circle c=new Circle(r1); //实例化Circle对象
c.getArea();
System.out.println("请输入矩形的边长:");
double x1=sc.nextDouble();
double y1=sc.nextDouble();
Rectangle re=new Rectangle(x1,y1); //实例化Rectangle对象
re.getArea();
}
}
(4)程序4源代码
//定义一个外部类
class Outer{
//下面的代码定义了一个静态内部类
static class Inner{
static String staticField="静态内部类的静态变量";
static void staticMethod(){
System.out.println("静态内部类的静态方法");
}
}
}
//定义测试类
public class Example4 {
public static void main(String[] args) {
Outer.Inner inner=new Outer.Inner();//创建内部类对象
System.out.println(inner.staticField);
inner.staticMethod();
}
}