Excise_Oop_abstract & Interface

1.下列代码的输出结果是:
public class A {
public void info(){
System.out.println(“A info”);
}
}
public class B extends A{
public void info(){
System.out.println(“B info”);
}
public static void main(String[] args) {
B b=new B();
A a=b;
a.info();
}
}
A. B info A info
B. A info B info
C. A info
D. B info

2.下列代码的输出结果是:
abstract class Vehicle{
public int speed(){
return 0;
}
}
class Car extends Vehicle{
public int speed(){
return 60;
}
}
class RaceCar extends Car{
public int speed(){
return 150;
}
}
public class TestCar {
public static void main(String[] args) {
RaceCar racer = new RaceCar();
Car car = new RaceCar();
Vehicle vehicle = new RaceCar();
System.out.print(racer.speed()+","+car.speed()+","+vehicle.speed());
}
}
A.0,0,0
B.150,60,0
C.150,150,150
D.抛出运行时异常

3.请看下列代码:
public abstract class Shape{
int x;
int y;
public abstract void draw();
public void setAnchor(int x,int y){
this.x=x;
this.y=y;
}
}
下列选项中能正确使用Shape类的是 D
A.public class Circle implements Shape{
private int radius;
}
B.public abstract class Circle implements Shape{//实现抽象类关键字使用extends
private int radius;
public void draw();
}
C.public class Circle extends Shape{
private int radius;
public void draw();没有方法体
}
D.public class Circle extends Shape{
private int radius;
public void draw(){/*code here */}
}

4.在Java语言中,下列说法正确的是
A. 一个接口可以继承多个接口
B. 一个类可以继承多个类
C. 一个类可以实现多个接口
D. 一个类可以有多个子类

5.下面关于Java接口的说法错误的是
A. 一个Java接口是一些方法特征的集合,但没有方法的实现
B. Java接口中定义的方法在不同的地方被实现,可以具有完全不同的行为
C. Java接口中可以声明私有成员
D. Java接口不能被实例化

6.在Java接口中,下列选项中属于有效的方法声明是
A. public void aMethod(); //缺啥补啥,接口中声明的方法如果省略public abstract 中的任意一个都会自动补齐。接口中的变量省略public static final 会自动补齐识别为静态常量。缺啥补啥
B. void aMethod();
C. void aMethod(){} 接口中的普通方法必须有default 或 static 显示声明,有方法体
D. private void aMethod(); 接口中的访问权限都是public ,接口中没有静态方法

7.在java 中,下列( ) 类不能派生出子类.
A. public class MyClass{ }
B. class MyClass{ }
C. abstract class MyClass{ }
D. final class MyClass { }

8.在Java中,下面关于抽象类的描述正确的是
A. 抽象类可以被实例化 因为实例化意味着在jvm的堆区中开辟一段内存

B. 如果一个类中有一个方法被声明为抽象的,那么这个类必须是抽象类

C. 抽象类中的方法必须都是抽象的 抽象类可以没有抽象方法

D. 声明抽象类必须带有关键字abstract

简答题
1.说说你对面向对象的理解
面向对象是一种编程思想,(以事物为驱动的编程思想)以属性和行为的特点去分析现实生活中的事物,将具有共有的属性和行为的多个事物封装成类;通过创建类,设计类的成员,创建类的对象,实现面向对象编程。

面向对象有三大特性,封装、继承和多态。
封装:

  • 封装类
    将一类事物共有的属性和行为封装成类,共有的属性封装成类的成员变量。共有的方法封装成类的成员方法
    封装类以便具有这些属性和行为的对象可以通过类创建

  • 封装方法
    将实现某一功能的代码封装成一个方法,实现代码的复用性,可维护性,安全性

  • 属性
    使用访问权限修饰符控制属性对外可见程度,通常使用private修饰属性,对外提供公共的方法访问其属性。

继承

  • 从已有的类中派生出新的类,派生出的类称为子类,派生类。被继承的类称为父类,超类,基类

  • 派生类继承父类方法和属性。子类不是父类的子集,而是父类的扩展。使用extends关键字建立继承关系

多态(重要)

  • 1.什么是多态:
    即是同一事物表现出来的多种形态
    主要是同一个对象,在不同时刻,代表的对象不一样。指的是对象的多种形态。

  • 实现多态的前提:
    继承
    重写 :成员变量和静态方法不存在重写现象,所以调用的都是父类的

  • 向上造型: 父类引用指向子类对象

  • 父类的引用指向子类的对象
    编译看左,运行看右
    编译看左:能调用什么看父类有什么
    运行看右:运行的结果看子类是否进行重写。如果重写了就调用子类重写后的方法体,否则直接使用父类的方法体。
    如果子类中重写了父类的方法。想调用父类的方法,只能再new 创建一个父类对象。不能使用一个指向子类对象的父类的引用调用被子类重写的方法。
    指向子类对象的父类引用想要调用子类特有的方法,必须向下造型(强转)

  • 向上造型:能(.出什么)调出什么看引用类型有什么,运行时输出什么,看子类是否重写父类的方法,如果子类重写了父类的方法,则输出子类重写后的方法体内容。否则输出父类方法体的内容

  • 多态的使用场合
    1,声明abstract 类型的引用 或 接口 的引用指向实现类对象,形成多态
    ① 创建对象时,父类引用指向子类对象。
    ② 使用父类类型作为形参,实现多态。形参为大类型,传入的实参可以与形参为同一类型,也可以为形参类型的子类型。
    ③ 使用父类作为方法的返回值类型实现多态。

  • 向下造型:
    ①前提是强转对象是以向上造型的方式创建的。
    必须保证 is a 关系。
    ②如果不是通过向上造型的方式创建的对象,在运行强转时不会编译报错。但是运行时会抛出类型转换异常:ClassCastException
    ③静态方法可以继承不能重写。子类定义方法声明和父类完全相同的静态方法,是子类自己的类方法,编译阶段就已经加载进内存,是该类自己特有的方法。多态父类引用指向子类对象,能调出什么看引用类型。

2.说一下abstract关键字的用法及作用
abstract 可以修饰类 和修饰方法。
被abstract修饰的类称为抽象类。抽象类中可以没有抽象方法,但是没有意义。
被abstract修饰的方法称为抽象方法,不能有方法体。连{}都没有。
作用:
抽象类的实际意义不在于创建对象,而在于被继承

3.简述抽象类和接口的区别
相同点:都可以有抽象方法,都不能被实例化(即是不能创建对象)(但是可以声明引用)。
不同点:
① 定义不同,声明接口使用interface ,声明抽象类使用 abstract class,
② 接口可以多继承,抽象类只能单继承(java中的类只能单继承)
③ 接口中只能有静态常量,抽象类中可以有普通变量。
④ 接口中没有构造方法,抽象类中有构造方法
⑤接口在JDK8之前只能有抽象方法,JDK8 之后可以有static 或 default修饰的普通方法,有方法体,接口中的普通方法必须显示使用static 或 default修饰,否则是抽象方法不能有方法体。 抽象类中可以有抽象方法,也可以有普通方法
⑥ 接口中的访问权限都是public 的,抽象类中四种访问权限都可以,
⑦ 接口中可以可以简写,接口中变量省略public static final 会自动拼接识别为静态常量, 接口中的方法可以省略public abstract会自动拼接识别为抽象方法,缺谁补谁。抽象类中不可以简写。

判断题
1.接口中只能有抽象方法 X,jdk8之前接口中只有抽象方法,JDK8 之后可以有static 或 default修饰的普通方法,有方法体,接口中的普通方法必须显示使用static 或 default修饰。 抽象类中可以有抽象方法,也可以有普通方法
2.abstract可以修饰类、方法、属性 X,abstract只能修饰类和方法,不能修饰属性
3.接口不能实例化,抽象类可以,因为接口没有构造方法,抽象类有构造方法X,抽象方法不能实例化,因为抽象类中可能有抽象方法。
4.类可以继承接口,接口可以实现接口X,类可以实现接口,接口可以继承接口
5.抽象类中必须有抽象方法,否则不能定义为抽象类X,抽象类中可以没有抽象方法

程序改错题
下述程序中都包含着错误而不能通过编译。请指出程序错误的原因(可指明行号),并修改程序使其可以通过编译。
程序:
01 abstract class Animal {
02 public abstract void saySomething() {** 方式一:去掉方法体,分号结尾;方式二:去掉abstract定义为普通方法**
03 System.out.println(“你想说什么就说吧!”);
04 }
05 }
06 class Dog extends Animal {
07 public void saySomething() {
08 System.out.println(“我现在有了第二职业:捉耗子!”);
09 }
10 }
11 public class Test {
12 public static void main (String[] args) {
13 Animal ani=new Dog();
14 ani.saySomething();
15 }
16 }

程序题
一、按照要求完成以下操作。
1.创建Person,Teacher,Student类。其中,Person为父类,Teacher和Student都继承Person
Person中有属性:String name,int age(是Teacher,Student中共有的属性,自己思考访问控制修饰符)
在Person中写出无参构造方法Person(),
有参构造方法Person(String name,int age),在方法体中为name,age赋值
在Person中定义方法:showMessage(),用于展示人的信息,打印输出“展示某个人的信息”

/*
* 1.创建Person,Teacher,Student类。其中,Person为父类,Teacher和Student都继承Person
    Person中有属性:String name,int age(是Teacher,Student中共有的属性,自己思考访问控制修饰符)
    在Person中写出无参构造方法Person(),
    有参构造方法Person(String name,int age),在方法体中为name,age赋值
    在Person中定义方法:showMessage(),用于展示人的信息,打印输出“展示某个人的信息”
* */
class Person{
    protected String name;
    protected int age;
    Person(){}
    Person(String name ,int age){
        this.name = name;
        this.age = age;
    }
    public void showMessage(){
        System.out.println("我叫 " + name + ", 今年 " + age + "岁");
    }

}

2.在Teacher类中定义私有的属性:工号:int teacherId
定义以下构造方法:
1.无参构造方法 Teacher()
2.有参构造方法Teacher(String name,int age,int teacherId)
该构造方法中调用父类的2个参数的构造方法,并为成员变量teacherId赋值为参数的值
在Teachar中重写方法showMessage():在方法体中输出“老师的信息是:姓名:xx,年龄:xx,工号:xx”

/*
* 2.在Teacher类中定义私有的属性:工号:int  teacherId
	定义以下构造方法:
	1.无参构造方法 Teacher()
	2.有参构造方法Teacher(String name,int age,int teacherId)
		该构造方法中调用父类的2个参数的构造方法,并为成员变量teacherId赋值为参数的值
	在Teachar中重写方法showMessage():在方法体中输出“老师的信息是:姓名:xx,年龄:xx,工号:xx”
* */
class Teacher extends Person{
    private int teacherId;
    Teacher(){}
    Teacher(String name,int age ,int teacherId){
        super(name,age);
        this.teacherId = teacherId;
    }

    @Override
    public void showMessage() {
        System.out.println("老师的信息是:" + name + ",年龄: " + age + ",工号:" + teacherId);
    }
}

3.在Student类中定义私有的属性:学号:int studentId
定义以下构造方法:
1.无参构造方法 Student()
2.有参构造方法Student(String name,int age,int studentId)
该构造方法中调用父类的2个参数的构造方法并为成员变量studentId赋值为参数的值
在Student中重写方法showMessage(): 在方法体中输出“学生的信息是:姓名:xx,年龄:xx,学号:xx”

/*
* 3.在Student类中定义私有的属性:学号:int studentId
	定义以下构造方法:
	1.无参构造方法 Student()
	2.有参构造方法Student(String name,int age,int studentId)
	该构造方法中调用父类的2个参数的构造方法并为成员变量studentId赋值为参数的值
	在Student中重写方法showMessage(): 在方法体中输出“学生的信息是:姓名:xx,年龄:xx,学号:xx”
* */
class Student extends Person{
    private int studentId;
    Student(){}
    Student(String name, int age,int studentId){
        super(name,age);
        this.studentId = studentId;
    }
    @Override
    public void showMessage(){
        System.out.println("学生的信息是:" + name + ",年龄: " + age + ",工号:" + studentId);

    }

4.写测试类Test
在main方法中创建Person[] ,长度为5, 存入2个老师,3个学生,之后遍历数组,调用showMessage()显示每个人的信息

/*
* 4.写测试类Test
	在main方法中创建Person[] ,长度为5,
	*  存入2个老师,3个学生,之后遍历数组,调用showMessage()显示每个人的信息
* */
public class PersonTest {
    public static void main(String[] args) {
        //使用多态特性:父类引用指向子类
        //1.创建Person[] ,长度为5,
        Person[] person = new Person[5];
        //2.存入2个老师,3个学生
        person[0] = new Teacher("江琳", 18,999);
        person[1] = new Teacher("江琳",18,999);
        person[2] = new Student("江琳", 18,666);
        person[3] = new Student("江琳", 18,666);
        person[4] = new Student("江琳", 18,666);
        //之后遍历数组
        for (int i = 0; i < person.length;i++){
            //调用showMessage()显示每个人的信息
            person[i].showMessage();
        }
    }

二、按要求完成以下代码:

  1. 定义接口Swim:
    抽象方法:swimming()
interface Swim{
    void swimming();
}
  1. 定义接口Fly:
    抽象方法:flying()
interface Fly{
    void flying();
}
  1. 定义类Bird:
    方法: layegg(){输出“鸟会下蛋”}
class Bird{
    public void layEgg(){
        System.out.println("鸟会下蛋!");
    }
}
  1. 定义类Penguin(企鹅):会游泳
    1. 继承Bird类
    2. 实现Swim接口,重写swimming(),输出“企鹅会游泳”
class Penguin extends Bird implements Swim{
    @Override
    public void swimming(){
        System.out.println("企鹅会游泳!");
    }
}
  1. 定义类Sparrow(麻雀):会飞
    1. 继承Bird类
    2. 实现Fly接口,重写flying(),输出“麻雀会飞”
class Sparrow extends Bird implements Fly{
    public void flying(){
        System.out.println("麻雀会飞!");
    }
}
  1. 定义类Eagle(老鹰):会飞
    1. 继承Bird类
    2. 实现Fly接口,重写flying(),输出“老鹰会飞”
class Eagle extends Bird implements Fly{
    @Override
    public void flying(){
        System.out.println("老鹰会飞!");
    }
}
  1. 创建Test类,main方法中:
    1. 创建Bird[],长度为5,向数组中存入2只企鹅,2只麻雀,1只老鹰
      2.遍历数组,若遍历到的对象是麻雀或老鹰,造型成Fly类型,调用flying();
      若遍历到的对象是企鹅,造型成Swim类型,调用swimming()
      提示:判断某个对象是否为某个类型时可以使用instanceof关键字,例如判断b是否为Fly类型,可以使用:b instanceof Fly,返回值为boolean类型,如果是为true,不是则为false。
7. 创建Test类,main方法中:
	1. 创建Bird[],长度为5,向数组中存入2只企鹅,2只麻雀,1只老鹰
* */
public class Test {
    public static void main(String[] args) {
        //1. 创建Bird[],长度为5,向数组中存入2只企鹅,2只麻雀,1只老鹰
        Bird[] birds =  new Bird[5];
        //向数组中存入2只企鹅
        birds[0] = new Penguin();
        birds[1] = new Penguin();
        //2只麻雀
        birds[2] = new Sparrow();
        birds[3] = new Sparrow();
        //1只老鹰
        birds[4] = new Eagle();

        /*
        * 2.遍历数组,若遍历到的对象是麻雀或老鹰,造型成Fly类型,调用flying();
		  若遍历到的对象是企鹅,造型成Swim类型,调用swimming()
	    提示:判断某个对象是否为某个类型时可以使用instanceof关键字,
	    * 例如判断b是否为Fly类型,可以使用:b instanceof Fly,返回值为boolean类型,
	    * 如果是为true,不是则为false。
        * */
        for (int i = 0; i < birds.length; i++){
            //若遍历到的对象是麻雀或老鹰,造型成Fly类型,调用flying();
            if (birds[i] instanceof Sparrow || birds[i] instanceof Eagle){
                Fly fly = (Fly)birds[i];
                fly.flying();
                //若遍历到的对象是企鹅,造型成Swim类型,调用swimming()
            }else if (birds[i] instanceof Swim){
                Swim swim = (Swim)birds[i];
                swim.swimming();
            }
        }
    }
}

总的代码实现

package JAVA_OOP.com.huacit.oopexcise.poly2;

/**
 * @author yyc
 */
/*
7. 创建Test类,main方法中:
	1. 创建Bird[],长度为5,向数组中存入2只企鹅,2只麻雀,1只老鹰
* */
public class Test {
    public static void main(String[] args) {
        //1. 创建Bird[],长度为5,向数组中存入2只企鹅,2只麻雀,1只老鹰
        Bird[] birds =  new Bird[5];
        //向数组中存入2只企鹅
        birds[0] = new Penguin();
        birds[1] = new Penguin();
        //2只麻雀
        birds[2] = new Sparrow();
        birds[3] = new Sparrow();
        //1只老鹰
        birds[4] = new Eagle();

        /*
        * 2.遍历数组,若遍历到的对象是麻雀或老鹰,造型成Fly类型,调用flying();
		  若遍历到的对象是企鹅,造型成Swim类型,调用swimming()
	    提示:判断某个对象是否为某个类型时可以使用instanceof关键字,
	    * 例如判断b是否为Fly类型,可以使用:b instanceof Fly,返回值为boolean类型,
	    * 如果是为true,不是则为false。
        * */
        for (int i = 0; i < birds.length; i++){
            //若遍历到的对象是麻雀或老鹰,造型成Fly类型,调用flying();
            if (birds[i] instanceof Sparrow || birds[i] instanceof Eagle){
                Fly fly = (Fly)birds[i];
                fly.flying();
                //若遍历到的对象是企鹅,造型成Swim类型,调用swimming()
            }else if (birds[i] instanceof Swim){
                Swim swim = (Swim)birds[i];
                swim.swimming();
            }
        }
    }
}

/*
* 1. 定义接口Swim:
	抽象方法:swimming()
* */
interface Swim{
    void swimming();
}
/*
* 2. 定义接口Fly:
	抽象方法:flying()
* */
interface Fly{
    void flying();
}
/*
* 3. 定义类Bird:
	方法: layegg(){输出“鸟会下蛋”}
* */
class Bird{
    public void layEgg(){
        System.out.println("鸟会下蛋!");
    }
}
/*
* 4. 定义类Penguin(企鹅):会游泳
	1. 继承Bird类
	2. 实现Swim接口,重写swimming(),输出“企鹅会游泳”
* */
class Penguin extends Bird implements Swim{
    @Override
    public void swimming(){
        System.out.println("企鹅会游泳!");
    }
}
/*
5. 定义类Sparrow(麻雀):会飞
	1. 继承Bird类
	2. 实现Fly接口,重写flying(),输出“麻雀会飞”
* */
class Sparrow extends Bird implements Fly{
    public void flying(){
        System.out.println("麻雀会飞!");
    }
}


/*
* 6. 定义类Eagle(老鹰):会飞
	1. 继承Bird类
	2. 实现Fly接口,重写flying(),输出“老鹰会飞”
* */
class Eagle extends Bird implements Fly{
    @Override
    public void flying(){
        System.out.println("老鹰会飞!");
    }
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值