面向对象编程(含java练习题)

Posted xingshouzhan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象编程(含java练习题)相关的知识,希望对你有一定的参考价值。

注:截图和题目多来自李刚老师的《疯狂Java讲义》,少部分为自己的理解,添加的相关说明和题目

 

一 类及其成员定义

   1.定义类(此处类定义不是内部类的定义,内部类定义请参考https://www.cnblogs.com/sxrtb/p/12651550.html

[修饰符] class 类名
{
  零个到多个构造器定义...
  零个到多个成员变量...
  零个到多个方法            
}

   修饰符可以是public、final、abstract,也可以省略。其中final和abstract只能出现一个

  

  2.定义成员变量

[修饰符] 类型 成员变量名 [=默认值];

  修饰符可以省略,也可以是public、private、protected、static、final,其中public、private、protected三个最多只能出现一个,可以与static、final组合起来修饰成员变量

 

  3.定义方法

[修饰符] 方法返回值类型 方法名(形参列表)
{
  //方法体      
}

  修饰符可以省略,也可以是public、private、protected、static、final、abstract,其中public、private、protected三个最多只能出现一个;abstract和final,abstract和static不能同时使用,final和static可以同时使用

 

  4.构造器 

[修饰符] 构造器名(形参列表)
{
  //构造器执行体  
}

  修饰符可以省略,也可以使public、private、protected其中之一。

 

  5.初始化代码块

  

  6.this的使用

  this总是指向调用该方法的对象(实际中的类型对象)或正在初始化的对象。

  出现位置:

    a.构造器第一行(标识正在初始化的对象)

    b.方法中

      调用另一个方法(和没有this效果一样)

      this.成员变量(防止被形参或者局部变量替换)

      方法中,默认(隐藏的)第一个参数为this,this可以在任何位置赋值给该类型对象

 

  7.方法的参数传递机制是值传递

class DataWrap
{
    int a;
    int b;
}
public class ReferenceTransferTest
{
    public static void swap(DataWrap dw)
    {
        int tmp = dw.a;
        dw.a = dw.b;
        dw.b = tmp;
        System.out.println("swap方法里,a成员变量的值是"
            + dw.a + ";b成员变量的值是" + dw.b);
        dw = null;
    }
    public static void main(String[] args)
    {
        DataWrap dw = new DataWrap();
        dw.a = 6;
        dw.b = 9;
        swap(dw);
        System.out.println("交换结束后,a成员变量的值是"
            + dw.a + ";b成员变量的值是" + dw.b);
    }
}

   8.形参个数可变的方法

    方法中最多只能有一个个数可变的形参,且位置只能出现在形参列表最后。

  9.形参个数可变的方法的重载

public class OverloadVarargs
{
    public void test(String msg)
    {
        System.out.println("只有一个字符串参数的test方法 ");
    }
    // 因为前面已经有了一个test()方法,test()方法里有一个字符串参数。
    // 此处的个数可变形参里不包含一个字符串参数的形式
    public void test(String... books)
    {
        System.out.println("****形参个数可变的test方法****");
    }
    public static void main(String[] args)
    {
        OverloadVarargs olv = new OverloadVarargs();
        // 下面两次调用将执行第二个test()方法
        olv.test();
        olv.test("aa" , "bb");
        // 下面将执行第一个test()方法
        olv.test("aa");
        // 下面调用将执行第二个test()方法
        olv.test(new String[]{"aa"});
    }
}

  10.用递归写出文件遍历

  

  11.方法重载

  注意两同一不同(同一个类中方法名相同,参数列表不同)

 

  12 父子类可以有方法的重载

 

  13 方法重载是一种静态行为,是一种动态分派(理解这一点,可以参考例题中的体现)

 

  12 注意,实例可以访问类,但是类不能访问实例

 

  14.所有变量及初始化

  

   实体变量和类变量都会自动初始值,但方法局部变量和代码块局部变量不会自动初始化,未初始化使用报错。

public class BlockTest
{
    public static void main(String[] args)
    {
        {
            // 定义一个代码块局部变量a
            int a;
            // 下面代码将出现错误,因为a变量还未初始化
             System.out.println("代码块局部变量a的值:" + a);
        }
    }
}

 

  15 数据在内存中的存储

  

   

  

  16 访问控制符

  

  17 是不是调用构造器就会创建一个对象

  

  18 java子类不能获得父类的构造器

 

  19 方法重写(两同两小一大)

  

 

  20 static方法中不会有this和supper

 

  21 若父类和子类中有相同的成员变量,内存图示

  

  

   22 多态

class BaseClass
{
    public int book = 6;
    public void base()
    {
        System.out.println("父类的普通方法");
    }
    public void test()
    {
        System.out.println("父类的被覆盖的方法");
    }
}
public class SubClass extends BaseClass
{
    //重新定义一个book实例变量隐藏父类的book实例变量
    public String book = "轻量级Java EE企业应用实战";
    public void test()
    {
        System.out.println("子类的覆盖父类的方法");
    }
    public void sub()
    {
        System.out.println("子类的普通方法");
    }
    public static void main(String[] args)
    {
        // 下面编译时类型和运行时类型完全一样,因此不存在多态
        BaseClass bc = new BaseClass();
        // 输出 6
        System.out.println(bc.book);
        // 下面两次调用将执行BaseClass的方法
        bc.base();
        bc.test();
        // 下面编译时类型和运行时类型完全一样,因此不存在多态
        SubClass sc = new SubClass();
        // 输出"轻量级Java EE企业应用实战"
        System.out.println(sc.book);
        // 下面调用将执行从父类继承到的base()方法
        sc.base();
        // 下面调用将执行从当前类的test()方法
        sc.test();
        // 下面编译时类型和运行时类型不一样,多态发生
        BaseClass ploymophicBc = new SubClass();
        // 输出6 —— 表明访问的是父类对象的实例变量
        System.out.println(ploymophicBc.book);
        // 下面调用将执行从父类继承到的base()方法
        ploymophicBc.base();
        // 下面调用将执行从当前类的test()方法
        ploymophicBc.test();
        // 因为ploymophicBc的编译类型是BaseClass,
        // BaseClass类没有提供sub方法,所以下面代码编译时会出现错误。
        // ploymophicBc.sub();
    }
}

  23 instanceof

  

public class InstanceofTest
{
    public static void main(String[] args)
    {
        // 声明hello时使用Object类,则hello的编译类型是Object,
        // Object是所有类的父类, 但hello变量的实际类型是String
        Object hello = "Hello";
        // String与Object类存在继承关系,可以进行instanceof运算。返回true。
        System.out.println("字符串是否是Object类的实例:"
            + (hello instanceof Object));
        System.out.println("字符串是否是String类的实例:"
            + (hello instanceof String)); // 返回true。
        // Math与Object类存在继承关系,可以进行instanceof运算。返回false。
        System.out.println("字符串是否是Math类的实例:"
            + (hello instanceof Math));
        // String实现了Comparable接口,所以返回true。
        System.out.println("字符串是否是Comparable接口的实例:"
            + (hello instanceof Comparable));
        String a = "Hello";
//        // String类与Math类没有继承关系,所以下面代码编译无法通过
//        System.out.println("字符串是否是Math类的实例:"
//            + (a instanceof Math));
    }
}

  24 将类设置成最终类的方法

    a.final

    b.所有方法都改成private

  

 题目

1.写出下面执行结果的输出

class Creature
{
    public Creature()
    {
        System.out.println("Creature无参数的构造器");
    }
}
class Animal extends Creature
{
    public Animal(String name)
    {
        System.out.println("Animal带一个参数的构造器,"
            + "该动物的name为" + name);
    }
    public Animal(String name , int age)
    {
        // 使用this调用同一个重载的构造器
        this(name);
        System.out.println("Animal带两个参数的构造器,"
            + "其age为" + age);
    }
}
public class Wolf extends Animal
{
    public Wolf()
    {
        // 显式调用父类有两个参数的构造器
        super("灰太狼", 3);
        System.out.println("Wolf无参数的构造器");
    }
    public static void main(String[] args)
    {
        new Wolf();
    }
}

2.解释下面程序为什么会报错

class Base
{
    public Base()
    {
        test();
    }
    public void test()           // ①号test()方法
    {
        System.out.println("将被子类重写的方法");
    }
}
public class Sub extends Base
{
    private String name;
    public void test()         // ②号test()方法
    {
        System.out.println("子类重写父类的方法,"
            + "其name字符串长度" + name.length());
    }
    public static void main(String[] args)
    {
        // 下面代码会引发空指针异常
        Sub s = new Sub();
    }
}

 3.下面方法体现了方法重载是一种静态行为,请写出运行结果(自拟题目)

public class OverloadMethod {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Animal dog = new Dog();
        Animal tiger = new Tiger();

        AnimalRun(animal);
        AnimalRun(dog);
        AnimalRun(tiger);
    }
    public static void AnimalRun(Animal animal){
        System.out.println("A");
    }
    public void AnimalRun(Dog dog){
        System.out.println("A");
    }
    public void AnimalRun(Tiger tiger){
        System.out.println("A");
    }

}

class Animal{
}
class Dog extends Animal{
}
class Tiger extends Animal{

}

 

  4.下面方法体现了方法重载是一种静态行为,并体现了多态的特征,请写出运行结果(自拟题目)

public class OverloadMethod {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Animal dog = new Dog();
        Animal tiger = new Tiger();

        AnimalRun(animal);
        AnimalRun(dog);
        AnimalRun(tiger);
    }
    public static void AnimalRun(Animal animal){
        System.out.println("A");
        animal.run();
    }
    public void AnimalRun(Dog dog){
        System.out.println("A");
        dog.run();
    }
    public void AnimalRun(Tiger tiger){
        System.out.println("A");
        tiger.run();
    }

}

class Animal{
    public void run(){
        System.out.println("Animal run");
    }
}
class Dog extends Animal{
    @Override
    public void run() {
        System.out.println("Dog run");
    }
}
class Tiger extends Animal{
    @Override
    public void run() {
        System.out.println("Tiger run");
    }
}

 

5.判断下面程序会不会报错

public class StaticTest {
    private static final StaticTest instance = new StaticTest();

    private StaticTest(){}


    public static void  a(){
        System.out.println("a");
        instance.b();
    }
    public void  b(){
        System.out.println("b");
    }

    public static void main(String[] args) {
        StaticTest.a();
    }
}

 

6.写出下面执行结果的输出

public class NullAccessStatic {
    private static void test()
    {
        System.out.println("static修饰的类方法");
    }
    private void run(){
        System.out.println("运行实例方法");
    }

    public static void main(String[] args)
    {
        NullAccessStatic nas = null;
        nas.test();
        nas.run();
    }
}

 

答案

1.

 

 

 2.

 

3.

 

4.

 

5不会

 

6.static修饰的类方法                     报错

 

  

 

以上是关于面向对象编程(含java练习题)的主要内容,如果未能解决你的问题,请参考以下文章

Java面向对象练习

VSCode自定义代码片段——JS中的面向对象编程

VSCode自定义代码片段9——JS中的面向对象编程

java 面向对象练习题11

java 面向对象练习题5

Java面向对象练习题之人员信息