Java6.面向对象编程(下)练习

1)下面关于接口的说法中不正确的是(C)。
A.接口中所有的方法都是抽象的
B.接口中所有的方法都是public访问权限
C.子接口继承父接口所用的关键字是implements
D.接口是Java中的特殊类,包含常量和抽象方法
2)Java语言接口间的继承关系是(A)。
A.单继承		B.多重继承			C.不能继承			D.不一定
3)一个类实现接口的情况是(A)。
A.一次可以实现多个接口				B.一次只能实现一个接口
C.不能实现接口						D.不一定
1)____interface_是声明接口的关键字,可以把它看成一个特殊类。接口中的数据成员默认的修饰符是__public static final___,接口中的成员方法默认的修饰符是___public abstract__。
2)如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须该接口的所有抽象方法;如果实现某接口的类是abstract的抽象类,则它可以该接口所有的方法。但是对于这个抽象类任何一个非抽象的子类而言,它们父类所实现的接口中的所有抽象方法以及自身所实现接口中的抽象方法都必须有实在的。
abstract classinterface 有什么区别? 
答:声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法

接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口
接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

答案是:   接口可以继承接口。抽象类可以实现(implements)接口,
抽象类可继承实体类,但实体类必须不能是如下两种情况之一:   
1final修饰符修饰的类是不能的
2,如果此实体类有且仅有私有的构造函数也是不能的。
是否能通过编译?
interface  A{
   int x = 0;
}
class B{
   int x =1;
}
class C extends B implements A {
   public void pX(){
      System.out.println(x);  //super.x   A.x(不能通过编译,因为不知道x是哪个的)
   }
   public static void main(String[] args) {
      new C().pX();
   }
}
答案:错误。在编译时会发生错误(错误描述不同的JVM有不同的信息,意思就是未明确的x调用,
两个x都匹配(就象在同时import java.util和java.sql两个包时直接声明Date一样)。对于父类的变量,可以用super.x来明确,
而接口的属性默认隐含为 public static final.所以可以通过A.x来明确。
interface A{}  

class B implements A{
public String func(){
return "func";
}
}

class Demo{
public static void main(String[] args){
A a=new B();
System.out.println(a.func());
}
}
//编译不通过:因为接口中没有此方法,通过堕胎不能调用子类中的方法
编一个程序,包含以下文件
(1)Shape.java文件,在该文件中定义接口类Shape,该接口在shape包中。
属性:PI。
接口:求面积的方法area()。
(2)Circle.java文件,在该文件中定义圆类Circle,该类在circle包中,实现Shape接口类。
属性:圆半径radius。
方法:构造器;实现求面积方法area();求周长方法perimeter()。
(3)Cylinder.java文件,在该文件中定义圆柱体类Cylinder,该类在cylinder包中,继承圆类。
属性:圆柱体高度height。
方法:构造器;求表面积方法area();求体积方法volume()。
(4)X5_3_6.java文件,在该文件中定义主类X5_3_6,该类在默认包中,其中包含主方法main(),在主方法中创建两个圆类对象cir1和cir2,具体尺寸自己确定,并显示圆的面积和周长;再创建两个圆柱体类的对象cy1和cy2,具体尺寸自己确定,然后分别显示圆柱体cy1和cy2的底圆的面积和周长以及它们各自的体积和表面积。
【编程分析】本题主要考察接口、包、继承、封装等问题。
package classTest5;
/**
 * describe:
 *
 * @author suoliang
 * @create 2021-06-19:17
 */
public class Shape1 {
    public static void main(String[] args) {
        Circle circle1 = new Circle(3);
        Circle circle2 = new Circle(4);
        System.out.println(circle1.area());
        System.out.println(circle1.perimeter());
        Cylinder cylinder1 = new Cylinder(3,4);
        Cylinder cylinder2 = new Cylinder(3,4);
        System.out.println(cylinder1.area());
        System.out.println(cylinder1.volume());

    }

}
interface Shape{
    public static final double PI = 3.14;
    public abstract double area();

}

class Circle implements Shape{
    private int radius;

    public Circle(int radius) {
        this.radius = radius;
    }

    public Circle() {
    }


    @Override
    public double area() {
        return Circle.PI * Math.sqrt(radius);
    }

    public double perimeter(){
       return 2 * Shape.PI * radius;
    }
}

class Cylinder extends Circle{
    private int height;

    public Cylinder(int radius, int height) {
        super(radius);
        this.height = height;
    }

    @Override
    public double area() {
        return super.area() * super.perimeter() * height;
    }

    public double volume(){
        return super.area() * height;
    }
}
请使用接口编码实现如下需求:乐器(Instrument)分为:钢琴(Piano)、小提琴(Violin).各种乐器的弹奏( play )方法各
不相同。编写一个测试类InstrumentTest,要求:编写方法testPlay,对各种乐器进行弹奏测试。要依据乐器的不同,进行相
应的弹奏。在main方法中创建不同的乐器对象,通过testPlay的弹奏测试方法进行测试。
package classTest5;

/**
 * describe:
 *
 * @author suoliang
 * @create 2021-06-19:34
 */
public interface Instrument {
    public abstract void play();
}

class Piano implements Instrument{

    @Override
    public void play() {
        System.out.println("Pinao can play");
    }
}

class Violin implements Instrument{
    @Override
    public void play() {
        System.out.println("Violin can play");
    }
}

class test15{
    public static void main(String[] args) {
        test15 test15 = new test15();
        test15.test(new Violin());
    }
    public void test(Instrument instrument){
        instrument.play();//多态,父类的引用指向子类的对象
    }
}
interface A{
	int x = 0;
}
class B{
	int x = 1;
}
class C extends B implements A{
	public void printX(){
		System.out.println(x);
	}
	public static void main(String[] args) {
		new C().printX();
	}
}
答案:编译错误
System.out.println(x);报错,x有歧义:不知道使用哪个
package classTest5;
计算器具有work方法,功能是运算,时钟同样具有work方法,功能是计时,有一个手机类Cellphone,同时需要拥有运算和计时功能,通过内部类实现多继承效果。

/**
 * describe:
 *
 * @author suoliang
 * @create 2021-06-19:44
 */
public class CellPhone implements Calculate,Time{
    @Override
    public void work() {
        Calculate.super.work();
        Time.super.work();

    }

    public static void main(String[] args) {
        CellPhone cellPhone = new CellPhone();
        cellPhone.work();
    }
}
interface Calculate{
    default void work(){
        System.out.println("计算机计算");
    }
}

interface Time{
    default void work(){
        System.out.println("时钟在⏲");
    }
}
abstract 的method 是否可同时是static,是否可同时是native,是否可同时是synchronized?
答:都不能
抽象类和抽象方法之间的关系
定义抽象类和抽象方法的关键字是(abstract)。抽象类中(可以)(可以/不可以)有抽象方法,(可以)(可以/不可以)有普通方法(可以)(可以/不可以)有属性;一个类中定义了抽象方法,那这个类(必须)(必须/不必须)用abstract修饰,即抽象类。
abstract class Name {
   private String name;
   public abstract boolean isStupidName(String name) {}
}
抽象类的话不能有括号
是否可以通过编译?
abstract class Something {
   private abstract String doSomething ();
}
不可用,使用private不能实现重写
abstract的methods不能以private修饰。abstract的methods就是让子类implement(实现)具体细节的,怎么可以用privateabstract method封锁起来呢? (同理,abstract method前不能加final)
tatic的使用
是否可以从一个static方法内部发出对非static方法的调用?
不可以,因为static方法可能不需要创建对象就使用,非静态方法必须要创建对象才可以使用
public class Something {
     public static void main(String[] args) {
        Something s = new Something();
        System.out.println("s.doSomething() returns " + doSomething());
    }
    public String doSomething() {
        return "Do something ...";
    }
}
//不可以,doSomething是非静态方法,不可用再static中直接调用
错。看上去在main里call doSomething没有什么问题,毕竟两个methods都在同一个class里。
但仔细看,main是static的。static method不能直接call non-static methods。
可改成"System.out.println("s.doSomething() returns " + s.doSomething());"。
同理,static method不能访问non-static instant variable。

public class Demo {
	private static int j = 0;

	private static boolean methodB(int k) {
		j += k;
		return true;
	}

	public static void methodA(int i) {
		boolean b;//默认false
		b = i < 10 | methodB(4);//j=4
		b = i < 10 || methodB(8);//第一个就是true,所以j=4
	}

	public static void main(String args[]) {
		methodA(0);
		System.out.println(j);
	}
}
谈谈final, finally, finalize的区别(后面异常中讲finally)
答:final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载

finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)

finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的
如下程序是否可通过编译?
public class Something {
   public int addOne(final int x) {
       return ++x;
   }
}
这个比较明显。
答案: 错。int x被修饰成final,意味着x不能在addOne method中被修改
如下程序是否可通过编译?
public class Something {
   public static void main(String[] args) {
       Other o = new Other();
       new Something().addOne(o);
   }
   public void addOne(final Other o) {
       o.i++;
   }
}
class Other {
   public int i;
}
和上面的很相似,都是关于final的问题,这有错吗?
答案: 正确。在addOne method中,参数o被修饰成final。如果在addOne method里我们修改了o的reference
(比如: o = new Other();),那么如同上例这题也是错的。但这里修改的是o的member vairable
(成员变量),而o的reference并没有改变。
是否可以通过编译?
class Something {
    int i;
    public void doSomething() {
        System.out.println("i = " + i);
    }
} 

答案: 正确。输出的是"i = 0"int i属於instant variable (实例变量,或叫成员变量)。instant variable有default value。
intdefault value是0
是否可以通过编译?
接上题
class Something {
    final int i;
    public void doSomething() {
        System.out.println("i = " + i);
    }
}
和上面一题只有一个地方不同,就是多了一个final。这难道就错了吗?
答案: 错。final int i是个final的instant variable (实例变量,或叫成员变量)final的instant variable没有default value,必须在constructor (构造器)结束之前被赋予一个明确的值。可以修改为"final int i = 0;"
以下代码的运行结果是?
public class Test {
	static int x, y, z;//类变量
	static {
		int x = 5;//这里的x--是相对于int x=5而言;
		x--;
	}
	static {
		x--;//这里面的是静态代码块,是对静态的x而言
	}
	public static void main(String[] args) {
		System.out.println("x=" + x);//-1,点击此处的x会发现int x = 5没有被点击,说明不是一个
		z--;//-1
		method();//y=0,z=1
		System.out.println("result:" + (z + y + ++z));
	}
	public static void method() {
		y = z++ + ++z;
	}
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值