类与 Object 的应用 + 面试题


类介绍

Java 程序是由若干个类组成的,类也是面向对象编程思想的具体实现。

以下为类的基本使用:

public class Cat {
// 私有属性
private String name;
private int age;
// 构造方法
public Cat() {
}
// 普通方法
public void eat() {
System.out.println("吃吃吃");
}
// 对外包装属性
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

类引用

当我们需要使用不同包下的类时,就需要使用 import 导入包或类,这个时候才能正常使用。例如,我们要使用 java.util 下的 ArrayList 就必须使用 import java.util.ArrayList,请参考以下代码:

// 导入 ArrayList 类
import java.util.ArrayList;
class importTest {
public static void main(String[] args) {
ArrayList list = new ArrayList();
}
}

类引用的高级用法

import 还可以导入静态方法和静态域的功能,比如以下代码:

// 导入 static 静态域的功能
import static java.lang.System.*;
class staticTest {
public static void main(String[] args) {
out.println("hi");
}
}

以上代码也可以顺利的执行,这也是 import 好玩的一个地方。

访问修饰符

在 Java 中访问修饰符有以下四种:

  • public
  • protected
  • 默认
  • private

具体介绍如下表:

(1)在开发中要尽可能地加上访问修饰符(提高程序的可读性);

(2)无特殊要求的情况下,类内部的变量应该设置为私有的(防止外部篡改)。

构造方法

构造方法也叫构造器或构造函数,它的作用是对类进行初始化,比如以下代码:

class Cat {
// 构造方法
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat cat = new Cat("喵星人",2);
System.out.println(cat.getName());
System.out.println(cat.getAge());
}
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

以上代码执行结果如下:

喵星人
2

构造方法五大原则:

  1. 构造方法必须与类同名;
  2. 构造方法的参数可以没有或者有多个;
  3. 构造方法不能有返回值;
  4. 每个类可以有一个或多个构造方法;
  5. 构造方法总是伴随着 new 操作一起使用。

继承

用法:使用 extends 关键字来实现类的继承,示例代码如下:

class Animal {
public void eat() {
System.out.println("Animal");
}
}
class Cat extends Animal {
}
public class eTest implements Cloneable {
public static void main(String[] args) {
Animal cat = new Cat();
cat.eat();
}
}

以上程序执行结果:Animal

继承使用技巧:

  • 将公共的变量或者方法提取到超类中;
  • 除非所有的方法都有继承的意义,否则不要使用继承;
  • 在方法覆盖时不要改变原有方法的预期行为。

Object

Object 类是 Java 中的一个特殊类,它是所有类的父类,Java 中的类都直接或间接的继承自 Object 类。

Object 类的常用方法如下:

  • equals():对比两个对象是否相同
  • getClass():返回一个对象的运行时类
  • hashCode():返回该对象的哈希码值
  • toString():返回该对象的字符串描述
  • wait():使当前的线程等待
  • notify():唤醒在此对象监视器上等待的单个线程
  • notifyAll():唤醒在此对象监视器上等待的所有线程
  • clone():克隆一个新对象

关于更多 Object 的内容,如克隆(深克隆、浅克隆)、线程等待和唤醒,会在后面的章节中详细介绍。

相关面试题

1. 类的组成部分有哪些?

答:在 Java 语言中,类主要是由方法和变量两部分组成。

2. 类与对象有哪些区别?

答:类是一个抽象的概念,是对某一事物的描述;而对象是类的实例,是实实在在存在的个体。比如,“人”就是一个类(一个概念),而老王(王磊)就是实实在在的一个“对象”。

3. Java 中可以多继承吗?

答:Java 中只能单继承,但可以实现多接口。

4. Java 中为什么不能实现多继承?

答:从技术的实现角度来说,是为了降低编程的复杂性。假设 A 类中有一个 m() 方法,B 类中也有一个 m() 方法,如果 C 类同时继承 A 类和 B 类,那调用 C 类的 m() 方法时就会产生歧义,这无疑增加了程序开发的复杂性,为了避免这种问题的产生,Java 语言规定不能多继承类,但可以实现多接口。

5. 覆盖和重载有哪些区别?

答:覆盖和重载的区别如下:

  • 覆盖(Override)是指子类对父类方法的一种重写,只能比父类抛出更少的异常,访问权限不能比父类的小,被覆盖的方法不能是 private,否则只是在子类中重新定义了一个方法;
  • 重载(Overload)表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同。

6. 以下不属于重载特性的是?

A:方法的参数类型不同

B:方法的返回值不同

C:方法的参数个数不同

D:方法的参数顺序不同

答:B

7. 为什么方法不能根据返回类型来区分重载?

答:因为在方法调用时,如果不指定类型信息,编译器就不知道你要调用哪个方法了。比如,以下代码:

float max(int x,int y);
int max(int x,int y);
// 方法调用
max(1,2);

因为 max(1,2) 没有指定返回值,编译器就不知道要调用哪个方法了。

8. 构造方法有哪些特征?

答:构造方法的特征如下:

  • 构造方法必须与类名相同;
  • 构造方法没有返回类型(void 也不能有);
  • 构造方法不能被继承、覆盖、直接调用;
  • 类定义时提供了默认的无参构造方法;
  • 构造方法可以私有,外部无法使用私有构造方法创建对象。

9. 构造函数能不能被覆盖?能不能被重载?

答:构造函数可以重载,但不能覆盖。

10. 以下说法正确的是?

A:类中的构造方法不能忽略

B:构造方法可以作为普通方法被调用

C:构造方法在对象被 new 时被调用

D:一个类只能有一个构造方法

答:C

11. 以下程序执行的结果是?

class ExecTest {
public static void main(String[] args) {
Son son = new Son();
}
}
class Parent{
{
System.out.print("1");
}
static{
System.out.print("2");
}
public Parent(){
System.out.print("3");
}
}
class Son extends Parent{
{
System.out.print("4");
}
static{
System.out.print("5");
}
public Son(){
System.out.print("6");
}
}

答:打印的结果是:251346

加载顺序如下:

  • 执行父类的静态成员;
  • 执行子类的静态成员;
  • 父类的实例成员和实例初始化;
  • 执行父类构造方法;
  • 子类的实例成员和实例初始化;
  • 子类构造方法。

12. 以下程序执行的结果是?

class A {
public int x = 0;
public static int y = 0;
public void m() {
System.out.print("A");
}
}
class B extends A {
public int x = 1;
public static int y = 2;
public void m() {
System.out.print("B");
}
public static void main(String[] args) {
A myClass = new B();
System.out.print(myClass.x);
System.out.print(myClass.y);
myClass.m();
}
}

答:打印的结果是:00B

题目解析:在 Java 语言中,变量不能被重写。

13. 以下程序执行的结果是?

class A {
public void m(A a) {
System.out.println("AA");
}
public void m(D d) {
System.out.println("AD");
}
}
class B extends A {
@Override
public void m(A a) {
System.out.println("BA");
}
public void m(B b) {
System.out.println("BD");
}
public static void main(String[] args) {
A a = new B();
B b = new B();
C c = new C();
D d = new D();
a.m(a);
a.m(b);
a.m(c);
a.m(d);
}
}
class C extends B{}
class D extends B{}

答:打印结果如下。

BA
BA
BA
AD

题目解析:

  • 第一个 BA:因为 A 的 m() 方法,被子类 B 重写了,所以输出是:BA;
  • 第二个 BA:因为 B 是 A 的子类,当调用父类 m() 方法时,发现 m() 方法被 B 类重写了,所以会调用 B 中的 m() 方法,输出就是:BA;
  • 第三个 BA:因为 C 是 B 的子类,会直接调用 B 的 m() 方法,所以输出就是:BA;
  • 第四个 AD:因为 D 是 A 的子类,所以会调用 A 的 m() 方法,所以输出就是:AD。

14. Java 中的 this 和 super 有哪些区别?

答:this 和 super 都是 Java 中的关键字,起指代作用,在构造方法中必须出现在第一行,它们的区别如下。

  • 基础概念:this 是访问本类实例属性或方法;super 是子类访问父类中的属性或方法。
  • 查找范围:this 先查本类,没有的话再查父类;super 直接访问父类。
  • 使用:this 单独使用时,表示当前对象;super 在子类覆盖父类方法时,访问父类同名方法。

15. 在静态方法中可以使用 this 或 super 吗?为什么?

答:在静态方法中不能使用 this 或 super,因为 this 和 super 指代的都是需要被创建出来的对象,而静态方法在类加载的时候就已经创建了,所以没办法在静态方法中使用 this 或 super。

16. 静态方法的使用需要注意哪些问题?

答:静态方法的使用需要注意以下两个问题:

  • 静态方法中不能使用实例成员变量和实例方法;
  • 静态方法中不能使用 this 和 super。

17. final 修饰符的作用有哪些?

答:final 修饰符作用如下:

  • 被 final 修饰的类不能被继承;
  • 被 final 修饰的方法不能被重写;
  • 被 final 修饰的变量不能被修改。

18. 覆盖 equals() 方法的时候需要遵守哪些规则?

答:Oracle 官方的文档对于 equals() 重写制定的规则如下。

  • 自反性:对于任意非空的引用值 x,x.equals(x) 返回值为真。
  • 对称性:对于任意非空的引用值 x 和 y,x.equals(y) 必须和 y.equals(x) 返回相同的结果。
  • 传递性:对于任意的非空引用值 x、y 和 z,如果 x.equals(y) 返回值为真,y.equals(z) 返回值也为真,那么 x.equals(z) 也必须返回值为真。
  • 一致性:对于任意非空的引用值 x 和 y,无论调用 x.equals(y) 多少次,都要返回相同的结果。在比较的过程中,对象中的数据不能被修改。
  • 对于任意的非空引用值 x,x.equals(null) 必须返回假。

此题目不要求记忆,能知道大概即可,属于加分项题目。

19. 在 Object 中 notify() 和 notifyAll() 方法有什么区别?

答:notify() 方法随机唤醒一个等待的线程,而 notifyAll() 方法将唤醒所有在等待的线程。

20. 如何使用 clone() 方法?

答:如果是同一个类中使用的话,只需要实现 Cloneable 接口,定义或者处理 CloneNotSupportedException 异常即可,请参考以下代码:

class CloneTest implements Cloneable {
int num;
public static void main(String[] args) throws CloneNotSupportedException {
CloneTest ct = new CloneTest();
ct.num = 666;
System.out.println(ct.num);
CloneTest ct2 = (CloneTest) ct.clone();
System.out.println(ct2.num);
}
}

如果非内部类调用 clone() 的话,需要重写 clone() 方法,请参考以下代码:

class CloneTest implements Cloneable {
int num;
public static void main(String[] args) throws CloneNotSupportedException {
CloneTest ct = new CloneTest();
ct.num = 666;
System.out.println(ct.num);
CloneTest ct2 = (CloneTest) ct.clone();
System.out.println(ct2.num);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class CloneTest2 {
public static void main(String[] args) throws CloneNotSupportedException {
CloneTest ct = new CloneTest();
ct.num = 666;
System.out.println(ct.num);
CloneTest ct2 = (CloneTest) ct.clone();
System.out.println(ct2.num);
}
}

总结

本文我们学习了类的基础用法,类引用:import 和 import static,访问修饰符的作用,构造函数和继承的特点以及使用技巧等,通过这些内容让我们对整个 Java 程序的组成,有了更加清晰直观的印象。


欢迎关注我的公众号,回复关键字“Java” ,将会有大礼相送!!! 祝各位面试成功!!!



%97%E5%8F%B7%E4%BA%8C%E7%BB%B4%E7%A0%81.png)

类与 Object 的应用的更多相关文章

  1. Java基础知识强化26(1):Object类之Object类的概述

    1.Object类 类Object是类层次结构的根类,每个类都使用 Object作为超类.所有对象(包括数组)都实现这个类的方法 每个类直接或者间接继承自Object类   2.Object类无参构造 ...

  2. Java基础12:深入理解Class类和Object类

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

  3. .NET基础 (11)类型的基类System.Object

    类型的基类System.Object1 是否存在不继承自System.Object类型的类2 在System.Object中定义的三个比较方法有何异同3 如何重写GetHashCode方法 类型的基类 ...

  4. JAVA中有一个特殊的类: Object

    JAVA中有一个特殊的类: Object.它是JAVA体系中所有类的父类(直接父类或者间接父类). 此类中的方法可以使所的类均继承. 以下介绍的三种方法属于Object: (1) finalize方法 ...

  5. 夯实Java基础系列9:深入理解Class类和Object类

    目录 Java中Class类及用法 Class类原理 如何获得一个Class类对象 使用Class类的对象来生成目标类的实例 Object类 类构造器public Object(); register ...

  6. day26——tyoe元类与object的联系、反射、函数与方法的区别、双下方法

    day26 type元类与object联系 type 获取对象从属于的类 python 中一切皆对象, 类在某种意义上也是一个对象,python中自己定义的类,以及大部分内置类,都是由type元类(构 ...

  7. java class类和object类

    Class类 介绍 Java的Class类是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息 Java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类( ...

  8. Google Guava学习笔记——基础工具类针对Object类的使用

    Guava 提供了一系列针对Object操作的方法. 1. toString方法 为了方便调试重写toString()方法是很有必要的,但写起来比较无聊,不管如何,Objects类提供了toStrin ...

  9. Java笔记:与系统交互、系统相关的类,Object类

    1.程序与用户交互 (1)运行一个Java程序的时候要给它提供一个main方法入口,这边分析一下这个main方法的签名public static void main(String[] args);pu ...

随机推荐

  1. Kafka学习笔记(四)—— API使用

    Kafka学习笔记(四)-- API使用 1.Producer API 1.1 消息发送流程 Kafka的Producer发送消息采用的是异步发送的方式.在消息发送的过程中,涉及到了两个线程--mai ...

  2. 011 RGW的SwiftAPi支持

    一. Swift简介 openstack swift是openstack开源云计算项目开源的对象存储,提供了强大的扩展性.冗余和持久性 1.1 swift特性 极高的数据持久性 完全对称的系统架构 无 ...

  3. 【题解】CF894E Ralph and Mushrooms (缩点)

    [题解]CF894E Ralph and Mushrooms (缩点) 这是紫?给个解方程算法 考虑一条边若可以重复遍历说明一定有环,有环的话一定会把环上的蘑菇榨干,考虑一条边从全部到榨干的贡献是多少 ...

  4. 洛谷$P3749$ [六省联考2017] 寿司餐厅 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 这道题好烦昂,,,就给了好多变量,,,但仔细读一遍题还是能$get$的所以我就不再提取一遍题目大意辣$QwQ$? 显然考虑建两排点,一排收益一排支出然后最小 ...

  5. 洛谷P1029 最大公约数和最小公倍数问题 题解

    题目链接:https://www.luogu.com.cn/problem/P1029 题目描述 输入 \(2\) 个正整数 \(x_0,y_0(2 \le x_0 \lt 100000,2 \le ...

  6. EF 学习系列二 数据库表的创建和表关系配置(Fluent API、Data Annotations、约定)

    上一篇写了<Entity Farmework领域建模方式 3种编程方式>,现在就Code First 继续学习 1.数据库表的创建 新建一个MVC的项目,在引用右击管理NuGet程序包,点 ...

  7. Java 从入门到进阶之路(二十一)

    在之前的文章我们介绍了一下 Java 中的日期操作,本章我们来看一下 Java 集合框架中的Collection. 早在 Java 2 中之前,Java 就提供了特设类.比如:Dictionary, ...

  8. 【转】最简单的安装pip的方法

    网上有各种方法安装pip,针对不同的系统方法还不一样,最后发现还是下面这种方法最简单,直接了当干脆方便,适用于Windows和Linux. (1)下载pip 进入https://pypi.python ...

  9. 【转】DB2数据库编目的概念以及对其的正确解析

    此文章主要向大家描述的是DB2数据库编目的概念以及对DB2数据库编目的概念的正确理解,在DB2中编目(catalog)这个单词看似很难理解,我自己当初在学习DB2数据库的时候也常常被这个编目搞的很不明 ...

  10. 【转】20个简化开发任务的 JavaScript库

    原文出处: codegeekz   译文出处: oschina 所谓JavaScript库就是预先写好的可以简化基于JavaScript的应用程序开发的,尤其是Ajax和其它以web为中心的技术的 J ...