实验三 JAVA 面向对象程序设计

一、实验目的和要求

掌握类、对象、方法、继承、接口的编程技术;
要求至少完成实验内容题的70%。(分工合作)
 

二、实验内容

程序设计题

3.编写一个包含圆类的程序,并为圆类设计几个构造方法和一般方法,在主方法中创建一个圆类对象并输出它的周长和面积。
要求:
属性有3个:x,y,r,分别放置圆心坐标和半径;
构造方法有2个。一个是无参的,用于设置3个属性的值都为0;另一个有参的,用于设置3个属性的值,以确定一个具体的圆。
计算周长的方法:double zc();
计算面积的方法:double mj()。
 
4.编写一个程序,它含有一个圆类、圆柱类和主类。
要求:
1)圆类参考上一题中的圆类;
2)圆柱类:继承圆类,并加入一个属性h(高);
构造方法(给4个属性赋值);
计算面积的方法(double mj());
计算体积的方法(double tj())。
注意,要充分利用父类的方法。
3)主类:在主方法中创建圆和圆柱类的对象,然后计算并输出它们的面积及圆柱的体积。

circle类

package TestCircle;

public class Circle {
    double centerX,centerY,radius;//三个属性,圆心坐标x,y和半径
    //无参构造,设置属性值为0
    public Circle(){
        centerX=0.0;
        centerY=0.0;
        radius = 0.0;
    }
    //带参构造,创建圆对象
    public Circle(double x, double y, double radius) {
        this.centerX = x;
        this.centerX = y;
        this.radius=radius;
    }
    //带参构造,创建圆对象,不关心圆心坐标
    public Circle(double rad) {
        radius = rad;
    }

    public double mj() {
        return radius*radius*Math.PI;
    }
    public double zc() {
        return 2*radius*Math.PI;
    }
    //计算周长的方法
    public double cmj(){
        return 2*Math.PI*radius; // 2*π*R
    }

    public void showInfo(){
        Circle c=new Circle(radius);
        System.out.println("圆的半径为:"+c.radius);
        System.out.println("圆的面积为:"+c.mj());
        System.out.println("圆的周长为:"+c.zc());
    }
}

Cylinder类

package TestCircle;

public class Cylinder extends Circle {
    private double height;
    //Circle cir = new Circle(radius);//设底面圆的半径
    //无参构造
    public Cylinder() {
        super();
        // TODO Auto-generated constructor stub
    }
    //含参构造
    public Cylinder(double radius, double height) {
        super(radius); //调用父类的Circle(double rad)构造函数,只关心半径
        this.height = height;
    }
    /*
     * 计算圆柱体表面积的方法
     * 圆底面积(π*R*R)*2+侧面积,就是底面周长*高(2*π*R*height)
     */
    public double mj2(){
        return (mj()*2 + cmj()*height);
    }
    /*
     * 计算圆柱体体积的方法
     * 圆底面积*高(π*R*R*height)
     */
    public double tj(){
        return mj()*height;
    }

    public void showInfo2(){
        System.out.println("圆柱体的半径为:" + radius);
        String str1 = String.format("圆柱体表面积为:%.2f", mj2());
        System.out.println(str1);
        String str2 = String.format("圆柱体的体积为:%.2f", tj());
        System.out.println(str2);
    }
}

Test类(测试用主类)

package TestCircle;
import java.util.Scanner;
public class Test {
    /**
     * 圆柱体和圆的测试类,就是题目中说的主类
     */
    public static void main(String[] args) {
        double rad;
        double[] c = new double[2];
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入圆的半径:");
        rad = sc.nextDouble();

        System.out.println("请输入圆柱体的半径,高:");
        for (int i = 0; i < 2; i++) {
            c[i] = sc.nextDouble();
        }sc.close();

        Circle cir = new Circle(rad);
        cir.showInfo();
        Cylinder cyl = new Cylinder(c[0], c[1]);
        cyl.showInfo2();
    }
}

运行截图
在这里插入图片描述 

阅读程序题

6.请仔细阅读下面的程序,分析程序的结构和输出结果。再将程序上机运行,验证输出结果。(重点理解:抽象类、抽象方法、(匿名)内部类、匿名对象)
abstract class A{abstract String getS();}
class Test
{ public static void main(String args[]){
System.out.println(new A(){ String getS(){ return “抽象?匿名?”;}}.getS());
}
}

abstract class A {
    abstract String getS();
    //抽象类中的抽象方法
}

class TestA {
    public static void main(String args[]){
        System.out.println
                ( new A() {String getS() { return "抽象?匿名?";}}.getS() );
        //等价于下面两句
        A a = new A(){String getS() { return "抽象?匿名?";}};
        System.out.println(a.getS());
    }
    //创建类对象,实现抽象类A,覆盖重写抽象类A的所有抽象方法
    //new出来的A是一个匿名内部类,只是实现了getS()方法,并不是new出了抽象类
    //这个对象a就是匿名内部类的实例,匿名类继承实现了抽象类
    //可以通过关键字来new一个抽象类来生成一个实例,但其实不是的,生成的仅仅是它的子类的对象
}

运行截图
在这里插入图片描述总结:
1、new出来的A是一个匿名内部类,只是实现了getS()方法,并不是new出了抽象类。这个对象a就是匿名内部类的实例,匿名类继承实现了抽象类。
2、抽象类不能直接new出来,如果要new出来必须使用匿名类的方式,匿名类其实就是声明了一个新的类来继承抽象类,所以你必须在匿名类实现所有抽象方法。
3、接口和抽象类类似,只不过里面的方法都是抽象方法,因此匿名类必须实现定义在接口里面的所有方法。
4、普通的非抽象的类也可以用匿名类new出来,只不过默认不需要实现任何方法,因为普通类里面没有抽象方法,当然你可以Override任何非私有方法。
 
—————————————————————————————————
 
7.请仔细阅读下面的程序,分析程序的结构和输出结果。再将程序上机运行,验证输出结果。
(重点理解:接口、接口实现方法、(匿名)内部类、匿名对象)
interface I{ String getS(); }
class Test
{ public static void main(String args[]){
System.out.println(new I(){ public String getS()
{ return “接口和内部类!”;}}.getS());
}
}
(请比较本程序与上题程序的不同之处)

interface I{
    String getS();
    //接口中的方法都是抽象的,等价于public abstract String getS();
}
class TestI {
    public static void main(String args[]){
        System.out.println
                ( new I(){ public String getS() { return "接口和内部类!";}}.getS() );
        //创建接口的匿名内部类对象,覆盖重写接口I的所有抽象方法
        //Anonymous new I() can be replaced with lambda
        I i = new I(){ public String getS() { return "接口和内部类!";}};
        System.out.println(i.getS());
    }
}

运行截图
在这里插入图片描述
总结
1、Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口,它简化了匿名委托的使用,让你让代码更加简洁,优雅。

2、匿名内部类是内部类的简化写法。它的本质是一个 带具体实现的 父类 或者 父接口的 匿名的 子类对象。
以接口举例,使用一个接口时,得做如下4步操作,

  1. 定义子类
  2. 重写接口中的方法
  3. 创建子类对象
  4. 调用重写后的方法

如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。

匿名内部类的定义格式:
接口名称 对象名 = new 接口名称() {
// 覆盖重写所有抽象方法
};

对格式“new 接口名称() {…}”进行解析:

  1. new代表创建对象的动作
  2. 接口名称就是匿名内部类需要实现哪个接口
  3. {…}这才是匿名内部类的内容
     

三、实验心得

Java的抽象类和内部类这块儿学得一塌糊涂。
列一些阅读和参考的blog。
 
java的抽象类,接口,普通类是否可以直接NEW,并且复写方法?
接口和抽象类可以被new嘛?——顺便总结内部类
阿里三面试题:为什么抽象类无法实例化,但是可以new出来实例?
记录:new一个抽象类到底new出了个什么东西
Java抽象类 详解
匿名内部类接口实现
Java挑战题——TestCircle(类的组合)
Lambda表达式详解(一)


版权声明:本文为qq_45670844原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。