【Java SE 复盘】Java面向对象编程基础:类与对象的创建

 

目录

 一,引言

二、类与对象的基本构成

1,类

三、构造方法机制详解

自动调用父类构造方法

this() 与 super() 的限制

四、常见陷阱 + 避坑指南

❗ 陷阱 1:this() 与 super() 混用导致编译错误

❗ 陷阱 2:静态方法中访问非静态变量

❗ 陷阱 3:super.方法() 不支持多态

Q1:构造方法能不能被 private 修饰?为什么?

 五,灵魂拷问,面试常客

Q1:构造方法能不能被 private 修饰?为什么?

Q2:构造方法能不能被继承?为什么?

Q3:this() 和 super() 可以同时出现在一个构造方法中吗?为什么?

Q4:静态方法中能不能访问非静态变量?为什么?

Q5:静态方法能被重写吗?它和普通方法的区别是什么?

Q6:main 方法为什么必须是 static 的?

Q7:default 权限(不加任何修饰符)是否允许跨包访问?

Q8:super 关键字能不能调用子类的方法?

七、总结


 一,引言

作为一名准备实习的 Java 程序员,你一定知道:面向对象编程(OOP)是 Java 的核心思想。而“类与对象”则是 OOP 的基石。我发现很多看似简单的知识点一旦被问深就容易卡壳。比如:

  • 构造方法能不能是 private?
  • this() 和 super() 可以共存吗?
  • 静态方法中为什么不能访问非静态变量? 今天我们就来系统梳理一下 Java 中类与对象的基础知识,并结合大量代码示例和常见误区,帮助你真正掌握这些在技术。

二、类与对象的基本构成

1,类

Java 是一门面向对象语言,类(class)是其核心概念。一个类通常包含:

  • 成员变量(属性)
  • 成员方法(行为)
  • 构造方法(初始化)
  • 静态成员(static)
public class Person {
    private String name; // 成员变量

    public Person(String name) { // 构造方法
        this.name = name;
    }

    public void sayHello() { // 成员方法
        System.out.println("Hello, I'm " + name);
    }
}

创建对象的基本方式是使用 new 关键字:

Person person = new Person("Tom");
person.sayHello();

注意

  • 如果没有手动定义构造方法,Java 会提供一个默认无参构造方法;
  • 一旦定义了带参构造方法,默认无参构造方法就会消失

三、构造方法机制详解

自动调用父类构造方法

子类构造方法默认会调用父类的无参构造方法(即隐式插入 super()),如果父类没有无参构造方法,则必须显式调用带参构造方法。

class Parent {
    public Parent(String name) {}
}

class Child extends Parent {
    public Child() {
        super("Tom"); // 必须显式调用
    }
}

this() 与 super() 的限制

  • 只能在构造方法中使用;
  • 必须出现在第一行
  • 二者不能同时出现
public class A {
    public A() {}
    public A(int x) {}
}

public class B extends A {
    public B() {
        this(10); // 正确
        // super(); ❌ 错误:不能共存
    }

    public B(int x) {
        super(); // 正确
    }
}

Q:构造方法可以继承吗?

💡 A:不可以。子类不会继承父类的构造方法,但可以通过 super() 调用。


四、常见陷阱 + 避坑指南

❗ 陷阱 1:this() 与 super() 混用导致编译错误

❌ 错误写法:

public class Student {
    public Student() {
        this("Tom");
        super(); // ❌ 编译错误:不能共存
    }
}

✅ 正确做法:

  • 选择其中一个;
  • 放在构造方法第一行。

❗ 陷阱 2:静态方法中访问非静态变量

❌ 错误写法:

public class Demo {
    int a = 10;
    static int b = 20;

    public static void method() {
        System.out.println(a); // ❌ 编译错误
    }
}

✅ 正确做法:

  • 将变量设为 static
  • 或者通过实例访问。

❗ 陷阱 3:super.方法() 不支持多态

❌ 错误理解:

class Animal {
    void speak() { System.out.println("Animal speaks"); }
}

class Dog extends Animal {
    void speak() { System.out.println("Dog barks"); }

    void test() {
        super.speak(); // 输出 "Animal speaks"
    }
}

📌 结论:

super.方法名() 是静态绑定,不涉及运行时多态。

Q1:构造方法能不能被 private 修饰?为什么?

构造方法是可以被 private 修饰的,这种设计常用于实现单例模式或工厂方法等设计模式。通过将构造方法设为私有,可以防止外部直接通过 new 创建对象,从而控制对象的创建方式。

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {} // 私有构造方法

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

📌 面试提示:

  • 如果你在代码中看到某个类的构造方法是 private,大概率是在使用单例或 Builder 模式;
  • 这也是控制对象生命周期和资源管理的一种手段。

 五,灵魂拷问,面试常客

Q1:构造方法能不能被 private 修饰?为什么?

构造方法是可以被 private 修饰的,这种设计常用于实现单例模式或工厂方法等设计模式。通过将构造方法设为私有,可以防止外部直接通过 new 创建对象,从而控制对象的创建方式。

例如:

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {} // 私有构造方法

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

📌 面试提示:

  • 如果你在代码中看到某个类的构造方法是 private,大概率是在使用单例或 Builder 模式;
  • 这也是控制对象生命周期和资源管理的一种手段。

Q2:构造方法能不能被继承?为什么?

构造方法是不能被继承的。子类不会自动拥有父类的构造方法,但它可以通过 super() 显式调用父类的构造方法。

举个例子:

class Parent {
    public Parent(String name) {}
}

class Child extends Parent {
    public Child() {
        super("Tom"); // 必须显式调用父类带参构造方法
    }
}

📌 原因解释:

  • 构造方法的作用是初始化当前类的对象状态;
  • 父类的构造方法无法直接用来初始化子类的状态;
  • 所以 Java 不允许继承构造方法,但允许通过 super() 调用。

Q3:this() 和 super() 可以同时出现在一个构造方法中吗?为什么?

不可以。在同一个构造方法中,this()super() 不能同时出现,而且它们都必须位于构造方法的第一行。

示例:

public class A {
    public A() {}
    public A(int x) {}
}

public class B extends A {
    public B() {
        this(10); // 正确
        // super(); ❌ 编译错误:不能共存
    }

    public B(int x) {
        super(); // 正确
    }
}

📌 原理说明:

  • this() 表示调用本类中的其他构造方法;
  • super() 表示调用父类的构造方法;
  • 它们都表示对对象初始化流程的控制,因此只能选其一,并且必须放在第一行执行。

Q4:静态方法中能不能访问非静态变量?为什么?

不能。静态方法属于类本身,而不是对象实例。而非静态变量是依赖于对象存在的,也就是说,在类加载时可能还没有任何实例存在,此时访问非静态变量就会导致错误。

示例:

public class Demo {
    int a = 10;
    static int b = 20;

    public static void method() {
        // System.out.println(a); ❌ 编译错误
        System.out.println(b); // ✅ 正确
    }
}

📌 面试追问:

“那如果我想在静态方法中访问非静态变量怎么办?”

解决方案:

  • 通过传入对象引用访问;
  • 或者先创建对象再访问:
public static void method() {
    Demo demo = new Demo();
    System.out.println(demo.a); // ✅ 正确
}

Q5:静态方法能被重写吗?它和普通方法的区别是什么?

静态方法不能被重写(Override),但可以被隐藏(Hide)。这是因为静态方法是静态绑定的,不是多态的一部分。

示例:

class Parent {
    static void method() {
        System.out.println("Parent");
    }
}

class Child extends Parent {
    static void method() {
        System.out.println("Child");
    }
}

// 测试
Parent p = new Child();
p.method(); // 输出 "Parent"

📌 结论:

  • 静态方法是根据编译时类型决定调用哪个方法;
  • 普通方法是根据运行时对象的实际类型来决定调用哪个方法;
  • 所以静态方法不支持多态,也不参与重写机制。

Q6:main 方法为什么必须是 static 的?

因为 JVM 在启动程序时还没有创建任何对象,所以需要通过类名直接调用 main 方法。而只有 static 方法才能在没有对象的情况下被调用。

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

📌 深入理解:

  • 如果 main 方法不是 static 的,JVM 就无法找到入口点;
  • 因此 main 方法必须声明为 static
  • 同时它还必须接收一个 String[] 类型的参数,否则也无法作为程序入口。

Q7:default 权限(不加任何修饰符)是否允许跨包访问?

不允许。default 权限(也就是不加任何访问修饰符)只允许在同一个包内访问,跨包访问会报错。

对比说明:

修饰符同包子类其他包
default
protected
public

📌 开发建议:

  • 对于工具类、辅助方法,尽量使用默认权限或 private
  • 控制访问范围有助于提升封装性和安全性。

Q8:super 关键字能不能调用子类的方法?

不能。super 只能访问父类的成员方法和变量,不能访问子类新增的成员。

示例:

class Animal {
    void speak() { System.out.println("Animal speaks"); }
}

class Dog extends Animal {
    void speak() { System.out.println("Dog barks"); }

    void test() {
        super.speak(); // 输出 "Animal speaks"
    }
}

📌 补充提问:

“super.speak() 会不会触发多态?”

不会。
super.方法名() 是静态绑定,不涉及运行时多态。

七、总结

面试重点内容
构造方法机制理解构造方法的作用、调用顺序、是否可继承
this 与 super 的使用掌握调用规则与限制
static 成员的本质理解静态方法与变量的生命周期
访问权限控制掌握 default、protected、private 的区别
类加载顺序了解静态代码块执行时机
开发最佳实践构造方法简洁、封装合理、避免空指针
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值