学习目标:JAVA面试八股文(一.Java基础篇)
提示:第一天开学
- OOP面向对象:
继承:继承是从已有类得到继承信息创建新类的过程
class Animal {
public void eat() {
System.out.println("动物吃东西");
}
}
class Cat extends Animal {
public void meow() {
System.out.println("猫喵喵叫");
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.eat(); // 继承自Animal类的方法
cat.meow(); // Cat类自己的方法
}
}
我们创建了一个Animal类,并定义了一个eat()方法。然后,我们创建了一个Cat类,并将其声明为Animal类的子类。Cat类还定义了一个meow()方法。在Main类中,我们创建了一个Cat对象,并调用了它继承自Animal类的eat()方法和自己的meow()方法。
封装:封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口
public class Person {
private String name; // 私有变量
public String getName() { // 公共方法
return name;
}
public void setName(String name) { // 公共方法
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person();
person.setName("张三");
System.out.println(person.getName()); // 输出:张三
}
}
我们创建了一个Person类,并将其属性name声明为私有变量。这意味着在类的外部无法直接访问该变量。我们还定义了两个公共方法getName()和setName(),分别用于获取和设置name属性的值。
在Main类中,我们创建了一个Person对象,并使用setName()方法将其name属性设置为"张三"。然后,我们使用getName()方法获取该对象的name属性,并将其输出到控制台。
多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应
class Animal {
public void makeSound() {
System.out.println("动物发出声音");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("狗发出汪汪的声音");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("猫发出喵喵的声音");
}
}
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
animal1.makeSound(); // 输出:狗发出汪汪的声音
animal2.makeSound(); // 输出:猫发出喵喵的声音
}
}
我们创建了一个Animal类,并定义了一个makeSound()方法。然后,我们创建了一个Dog类和一个Cat类,它们都是Animal类的子类,并重写了makeSound()方法以实现各自特定的声音。
在Main类中,我们创建了一个Animal类型的引用animal1,并将其指向一个Dog对象。我们还创建了一个Animal类型的引用animal2,并将其指向一个Cat对象。然后,我们通过调用animal1和animal2的makeSound()方法,实际上是调用了对应子类的makeSound()方法。
- 重载与重写L:
重载:方法重载是指在一个类中可以定义多个方法,它们具有相同的名称但是参数列表不同的特性。在Java中,方法重载允许我们使用相同的方法名来执行不同的操作,只要这些方法的参数列表不同即可。
public class Calculation {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public String add(String a, String b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
Calculation calculation = new Calculation();
System.out.println(calculation.add(1, 2)); // 输出:3
System.out.println(calculation.add(1.5, 2.5)); // 输出:4.0
System.out.println(calculation.add("Hello", "World")); // 输出:HelloWorld
}
}
我们创建了一个Calculation类,并定义了三个名为add的方法,它们具有不同的参数类型和数量。第一个add方法接受两个int类型的参数,第二个add方法接受两个double类型的参数,第三个add方法接受两个String类型的参数。
在Main类中,我们创建了一个Calculation对象,并分别调用了这三个不同版本的add方法。由于它们的参数列表不同,编译器能够根据调用时传入的参数类型和数量来确定调用哪个版本的add方法。
重写:方法重写是指子类重新定义其父类中已有的方法的行为。在Java中,当子类定义一个与父类中具有相同名称、参数列表和返回类型的方法时,就发生了方法重写。
class Animal {
public void makeSound() {
System.out.println("动物发出声音");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("狗发出汪汪的声音");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.makeSound(); // 输出:狗发出汪汪的声音
}
}
在Main类中,我们创建了一个Animal类型的引用animal,并将其指向一个Dog对象。当我们调用animal的makeSound()方法时,实际上调用的是Dog类中重写的makeSound()方法。
- 接口与抽象类的区别:
接口:指一种定义了一组方法签名的抽象类型。在Java中,接口可以看作是一个完全抽象的类,它只包含了方法的声明而没有方法的实现。
interface Animal {
void makeSound();
void eat();
}
class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("狗发出汪汪的声音");
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.makeSound(); // 输出:狗发出汪汪的声音
animal.eat(); // 输出:狗吃骨头
}
}
抽象类:抽象类(Abstract Class)是指用关键字abstract声明的类,它不能被实例化,只能被继承。抽象类可以包含抽象方法和非抽象方法,但是抽象方法必须在子类中被实现。
abstract class Animal {
public abstract void makeSound();
public void sleep() {
System.out.println("动物正在睡觉");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("狗发出汪汪的声音");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.makeSound(); // 输出:狗发出汪汪的声音
animal.sleep(); // 输出:动物正在睡觉
}
}
- 深拷贝与浅拷贝的理解 :
深拷贝和浅拷贝就是指对象的拷贝,一个对象中存在两种类型的属性,一种是基本数据类型,一种是实例对象的引用。
*浅拷贝是指,只会拷贝基本数据类型的值,以及实例对象的引用地址,并不会复制一份引用地址所指向的对象,也就是浅拷贝出来的对象,内部的类属性指向的是同一个对象
深拷贝是指,既会拷贝基本数据类型的值,也会针对实例对象的引用地址所指向的对象进行复制,深拷贝出来的对象,内部的类执行指向的不是同一个对象
- sleep和wait区别:
sleep:在Java中,Thread类提供了sleep()方法用于暂停当前线程的执行。它接受一个以毫秒为单位的时间参数,表示线程需要休眠的时间。
public class Main {
public static void main(String[] args) {
System.out.println("程序开始");
try {
// 暂停当前线程的执行1秒钟
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("程序继续执行");
}
}
wait:wait()是Object类提供的一个方法,用于让线程暂停执行并等待其它线程通知。当一个线程调用了wait()方法后,它会释放所持有的对象锁,并进入到该对象的等待池中,直到其它线程调用该对象的notify()或notifyAll()方法唤醒它。
public class Main {
public static void main(String[] args) {
final Object lock = new Object();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("线程1获取锁并等待");
try {
lock.wait(); // 线程1等待并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1被唤醒");
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("线程2获取锁并唤醒");
lock.notify(); // 唤醒线程1
}
}
});
thread1.start();
thread2.start();
}
}
11.==
和equals区别:
==:
如果比较的是基本数据类型,那么比较的是变量的值
如果比较的是引用数据类型,那么比较的是地址值(两个对象是否指向同一块内存)
equals
如果没重写equals方法比较的是两个对象的地址值
如果重写了equals方法后我们往往比较的是对象中的属性的内容
equals方法是从Object类中继承的,默认的实现就是使用==