java基础郎波版chapter4习题

1.试说明Java语言是如何支持多重继承的。

JAVA不直接支持多重继承,以避免多继承带来的复杂性和潜在的“菱形问题”。但是Java通过接口(interface)实现了多重继承的概念。一个类可以实现多个接口,从而实现多个接口中的抽象方法,达到多重继承的效果。

2.类的构造方法和成员方法之间有什么区别?

构造方法:

主要用于初始化对象,具有与类名一样的名称,没有返回类型,即使是void也不需要。在创建对象时自动调用,可以有参数列表

成员方法:

也称为实例方法,是类的一部分,用于定义对象的行为或操作数据。有具体的返回类型,可以在类中的任何地方被调用。

3.编写程序片段,定义表示课程的类Course。

课程的属性包括课程名、编号、先修课号;
方法包括设置课程名、设置编号、设置先修课号以及获取课程名、获取编号、获取先课号。

package com.example.demo.chapter;

/**
 * @author zyk
 * @date 2024/4/30 上午7:18
 * @return
 */
public class Course {
    private String courseName;
    private int courseId;
    private String firstCourseName;
    public Course(String courseName, int courseId, String firstCourseName){
        this.courseName = courseName;
        this.courseId = courseId;
        this.firstCourseName = firstCourseName;
    }
    public String getCourseName() {
    return courseName;
    }
    public void setCourseName(String courseName) {
    this.courseName = courseName;
    }
    public int getCourseId() {
    return courseId;
    }
    public  void setCourseId(int courseId) {
    this.courseId = courseId;
    }
    public String getFirstCourseName() {
    return firstCourseName;
    }
    public void setFirstCourseName(String firstCourseName) {
    this.firstCourseName = firstCourseName;
    }
    public void printCourse(){
    System.out.println("课程名称:"+courseName+"课程编号:"+courseId+"课程名称:"+firstCourseName);
    }
    public static void main(String[] args) {
    Course course = new Course("java",1,"java");
        System.out.println("course = " + course);
        System.out.println("course.getCourseName() = " + course.getCourseName());
        course.setCourseName("zhengyangkang");
        System.out.println("course.getCourseName() = " + course.getCourseName());
    }

    @Override
    public String toString() {
    return "Course{" +
        "courseName='" + courseName + '\'' +
        ", courseId=" + courseId +
        ", firstCourseName='" + firstCourseName + '\'' +
        '}';
    }
}

注意,如果这里没有添加toString(),既没有重写tostring函数,则打印出来是这样的形式
在这里插入图片描述
Java中,当你尝试打印一个对象(而非基本类型)时,如果没有重写toString()方法,那么默认会调用Object类的toString()方法。这个方法返回的是对象的类名加上@,然后是对象哈希码的十六进制表示
在这里插入图片描述

在这个例子中,course是一个Course对象,所以course.toString()的结果是"com.example.demo.chapter.Course@79fc0f2f"。这里的部分解释如下:
com.example.demo.chapter.Course:这是Course类的全限定类名(包名+类名)。
@:分隔符,表示接下来的部分是对象的哈希码。
79fc0f2f:这是对象在内存中的地址(或者说是哈希码),以十六进制形式表示。这个值是唯一的,除非两个对象在内存中的位置相同,否则不同的对象会有不同的哈希码。
如果你希望在打印对象时显示更有意义的信息,你可以为Course类重写toString()方法,返回自定义的字符串表示。例如:

加上重写的tostring()后,则再次打印就会出现

@Override
public String toString() {
    return "Course{" +
            "courseName='" + courseName + '\'' +
            ", courseId=" + courseId +
            ", firstCourseName='" + firstCourseName + '\'' +
            '}';
}

在这里插入图片描述
这是具体的类信息的,不再是内存地址。

4.编写程序创建习题3中的Course类的对象,设置并打印输出该对象的课程名、编号以及先修课号。

java里面的main函数就和C里面的main函数一样的。想要执行必须到main函数里面来。只不过这里的

不是的,不是每一个Java类都必须包含一个main函数。main函数是Java程序的入口点,只有包含main函数的类才能被Java虚拟机(JVM)直接执行。当你运行一个Java程序时,你需要指定包含main方法的类,JVM会从这个main方法开始执行代码。

如果你编写的是一个库或者一个类,这些类通常不会包含main方法,因为它们的作用是为了被其他类调用,而不是直接运行。例如,你可能会定义一些工具类、数据结构类或业务逻辑类,这些类内部的方法是为了提供服务或实现特定功能,而不是作为程序的起点。
所以,是否包含main方法取决于类的设计和用途。如果一个类是用来启动一个独立的应用程序,那么它需要main方法;如果是用来作为组件或服务给其他类使用,那么就不需要main方法。

5.Java中方法调用的参数传递方式是什么?

在Java中,参数传递总是遵循“按值传递”的原则,无论参数是基本类型还是引用类型。这意味着:

基本类型参数:

当传递基本类型的参数(如int、double、char等)时,方法接收到的是这些变量值的一个副本。这意味着在方法内部对这些参数的任何修改都不会影响到方法外部的基本类型变量。例如,如果一个方法接收一个int类型的参数,它在方法内部增加该参数的值,这种方法调用结束后,原始变量的值保持不变。

引用类型参数:

对于对象参数,情况稍微复杂一些。虽然也是按值传递,但传递的是对象引用的一个副本,而不是对象本身。这意味着方法得到的是原始对象引用的一个拷贝,这个拷贝和原始引用指向相同的对象实例。
因此,如果在方法内部通过引用修改对象的属性(比如对象的字段),这些修改会反映到原始对象上,因为它们都是指向同一个对象实例。例如,如果一个方法接收一个String类型的对象参数,它在方法内部更改该字符串的内容,这种方法调用结束后,外部访问该对象也会看到内容的变化。

但是,如果在方法内部重新赋值给这个引用(例如,让这个引用指向一个新的对象),这个改变只发生在方法内部,不会影响到外部的引用,也就是说,外部的引用仍然指向原来的对象。
总结来说,Java中的参数传递保证了方法内部的操作不会影响到外部变量的直接引用,但对于对象,由于引用的传递,可以影响到共享的同一对象实例的状态。

下面这段代码解释了传递参数为对象的情况

class Student {
    String name;

    public Student(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}

public class ParameterPassingExample {

    public static void main(String[] args) {
        Student originalStudent = new Student("Alice");

        System.out.println("Before method call: originalStudent = " + originalStudent);

        modifyStudent(originalStudent);

        System.out.println("After method call: originalStudent = " + originalStudent);
    }

    public static void modifyStudent(Student student) {
        // 改变对象的属性,这会影响外部的originalStudent,因为它们指向同一个对象
        student.setName("Bob");

        System.out.println("Inside method: student after setName = " + student);

        // 重新赋值引用,让student指向一个新的对象
        student = new Student("Charlie");

        System.out.println("Inside method: student after reassignment = " + student);
    }
}

在这里插入图片描述

可以看到,尽管在方法内部student引用被指向了一个新对象,但外部的originalStudent对象保持未变,仍然是名字为"Bob"的学生对象。这证明了虽然对象引用是按值传递的,但通过引用修改对象状态会影响到外部,而直接改变引用本身的指向则不会。(student只是一个存在于栈中的变量而已)

6.this 关键字的作用是什么?

this关键字在Java中代表当前对象的引用,它可以用来访问当前对象的成员变量、调用当前对象的方法,或者在构造函数中引用当前类的其他构造函数。

7.一个类中的方法,要使同一个包中的类可以访问而其他类不能访问,应该使用怎样的访问控制?

如果一个类中的方法要让同一包内的其他类可以访问,但不允许包外的类访问,应该使用protected访问修饰符。protected比private更开放,但比public更限制,只允许同包内和子类访问

8.什么是方法重载?方法重载的规则是什么?

方法重载是指在同一个类中可以有多个同名方法,但这些方法的参数列表必须不同(即参数的数量、类型或顺序不同)。
返回类型不是区分重载方法的关键因素,因为调用方法是基于传入的参数,而不是返回类型

9.什么是方法重写?方法重写的规则是什么?

方法重写发生在子类中,子类提供与父类同名且参数列表完全相同的方法
重写的方法必须有相同的返回类型,名字和参数列表。
访问权限不能更低,可以更高,但不能是private
方法的访问修饰符、返回类型、参数列表和抛出的异常必须与被重写的方法匹配。
子类方法必须声明为@Override(可选,但推荐),以确保是故意重写父类方法

10.试说明Java语言中多态的含义及实现机制

多态是指一个接口可以有多种不同的行为,或者一个对象可以表现出多种形态。
在Java中,多态分为编译时多态(通过方法重载实现)和运行时多态(通过方法重写和接口实现实现)。
运行时多态是通过引用父类类型的对象来调用子类的方法,这依赖于对象的实际类型(动态绑定)。
实现多态的关键是面向对象的特性:继承、抽象类和接口,以及方法的重写和重载。

11.给出下列程序的运行结果。

package com.example.demo.chapter;

/**
 * @author zyk
 * @date 2024/4/30 上午8:48
 * @return
 */
class Meal {
    Meal(){System.out.println("Meal( )"); }
}

    class Bread {
    Bread(){ System.out.println("Bread()");}
    };

        class Cheese {
            Cheese(){
                System.out.println("Cheese()");}
        }

            class Lettuce {
                Lettuce() {
                    System.out.println("Lettuce()");}
            }


class launch extends Meal {
    launch() {
        System.out.println("Lunch()");
    }
}

        class PortableLunch extends launch {
            PortableLunch() {
                System.out.println("PortableLunch()");
            }
        }


        public class Sandwich extends PortableLunch {

            private Bread b = new Bread();
            private Cheese c = new Cheese();
            private Lettuce l = new Lettuce();

            public Sandwich() {
                System.out.println("Sandwich()");
            }
            public static void main(String[] args){
                    new Sandwich();
            }
        }

在这里插入图片描述
先将父类的该打印的打印出来,自身的再议

比如这里的Sandwich类,集成的portableLaunch类,而portableLaunch类又继承自Launch类,而Launch又继承自meal类,所以就是最先打印的是Meal,再是lunch,再是portableLunch,最后再是从自身向下打印,包括字段的对象,自身的构造函数等等……

这里还需注意一点就是,多个类可以在同一个.java文件夹之下,但是文件夹名称必须是public的类的名称
比如这里就是Sandwich.java。不然会报错。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值