IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java面向对象【Java面试题】 -> 正文阅读

[Java知识库]Java面向对象【Java面试题】

1、面向对象包括哪些特性,怎么理解的?

(1)封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。
面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。
我们在类中编写的方法就是对实现细节的一种封装;
我们编写一个类就是对数据和数据操作的封装。
可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口。

package cn.itbluebox.springbootactuator;
class A{
    private String name;
    private int age;
    public A() {
    }
    public A(String name, int age) {
        this.name = name;
        this.age = 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;
    }
}
public class Test {
    public static void main(String[] args) {
        A a = new A();
        a.setAge(12);
        a.setName("张三");
        int age = a.getAge();
        String name = a.getName();
        System.out.println("age"+age);
        System.out.println("name"+name);
    }
}

运行测试
在这里插入图片描述

(2)继承:继承是从已有类得到继承信息创建新类的过程。
提供继承信息的类被称为父类(超类、基类);
得到继承信息的类被称为子类(派生类)。
继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段。

package cn.itbluebox.springbootactuator;

class A{
    public void a(){
        System.out.println("aaaaaaaa");
    }
}
class B extends A{
}
public class Test {
    public static void main(String[] args) {
        B b = new B();
        b.a();
    }
}

在这里插入图片描述

(3)多态:多态性是指允许不同子类型的对象对同一消息作出不同的响应。
简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。
多态性分为编译时的多态性和运行时的多态性。
如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:
当 A系统访问B系统提供的服务时,B 系统有多种提供服务的方式,但一切对 A 系统来说都是透明的。
方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。
运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:

第一:方法重写(子类继承父类并重写父类中已有的或抽象的方法);

第二:对象造型(用父类型引用指向子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。

package cn.itbluebox.springbootactuator;
class A{
    public void a(){
        System.out.println("aaaaaaaa");
    }
    public void o(){
        System.out.println("bobobobobobo");
    }
}
class B extends A{
    public void o(){
        System.out.println("bobobobobobo");
    }
}
class C extends A{
    public void o(){
        System.out.println("cocococococo");
    }
}
public class Test {
    public static void main(String[] args) {
        A a = new B();
        a.o();
        a = new C();
        a.o();
    }
}

在这里插入图片描述
(4)抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。

package cn.itbluebox.springbootactuator;
abstract class A{
    public abstract void o();
}
class B extends A{
    @Override
    public void o() {
        System.out.println("bobobo");
    }
}
class C extends A{
    @Override
    public void o() {
        System.out.println("cococo");
    }
}
public class Test {
    public static void main(String[] args) {
        A a = new B();
        a.o();
        a = new C();
        a.o();
    }
}

在这里插入图片描述

2、访问权限修饰符 public、private、protected, 以及不写(默认)时的区别?

在这里插入图片描述

3、Java中为什么要用 clone?

在实际编程过程中,我们常常要遇到这种情况:
有一个对象 A,在某一时刻 A 中已经包含了一些有效值,此时可能会需要一个和 A 完全相同新对象 B,并且此后对 B 任何改动都不会影响到 A 中的值,也就是说,A 与 B 是两个独立的对象,但 B 的初始值是由 A 对象确定的。
在 Java 语言中,用简单的赋值语句是不能满足这种需求的。
要满足这种需求虽然有很多途径,但clone()方法是其中最简单,也是最高效的手段。

● 说到对象的克隆,涉及到深克隆和浅克隆?

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

new一个对象的过程和clone一个对象的区别?
new 操作符的本意是分配内存。程序执行到 new 操作符时,首先去看 new 操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。

分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。

clone 在第一步是和 new 相似的,都是分配内存,调用 clone 方法时,分配的内存和原对象(即调用 clone 方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域,填充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。

(1)实际案例

1)单纯的复制对象

package cn.itbluebox.springbootactuator;

class Student{
    private int age;
    private String name;
    public Student() {
    }
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1 = new Student();
        student1.setAge(12);
        Student student2 = student1;
        System.out.println("学生1:" + student1.getAge());
        System.out.println("学生2:" + student2.getAge());
    }
}

运行
在这里插入图片描述
当我们更改student1的值的时候student2也会被修改

package cn.itbluebox.springbootactuator;

class Student{
    private int age;
    private String name;
    public Student() {
    }
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1 = new Student();
        student1.setAge(12);
        Student student2 = student1;
        student1.setAge(30);
        System.out.println("学生1:" + student1.getAge());
        System.out.println("学生2:" + student2.getAge());
    }
}

在这里插入图片描述
在这里插入图片描述
原因出在(student2= student1) 这一句。该语句的作用是将student1的引用赋值给student2,

这样,student1和student2指向内存堆中同一个对象。

修改其中一个则另外一个也会改变
在这里插入图片描述

2)如何实现克隆

01)浅克隆
  1. 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常), 该接口为标记接口(不含任何方法)

  2. 覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。(native为本地方法)

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。

简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。

package cn.itbluebox.springbootactuator;

class Student implements Cloneable{
    private int age;
    private String name;
    public Student() {
    }
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public Object clone() {
        Student stu = null;
        try{
            stu = (Student)super.clone();
        }catch(CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return stu;
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1 = new Student();
        student1.setAge(12);
        Student student2 = (Student)student1.clone();
        student1.setAge(30);
        System.out.println("学生1:" + student1.getAge());
        System.out.println("学生2:" + student2.getAge());
    }
}

student1在赋值年龄12之后clone创建student2 ,然后更改student1的值是不会影响student2 的值的
在这里插入图片描述

02)深度克隆:

在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。

简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。
错误案例

package cn.itbluebox.springbootactuator;

class Address{
    private String add;
    public Address() {
    }
    public Address(String add) {
        this.add = add;
    }
    public String getAdd() {
        return add;
    }
    public void setAdd(String add) {
        this.add = add;
    }
}
class Student implements Cloneable{
    private int age;
    private Address address;
    public Student() {
    }
    public Student(int age, Address address) {
        this.age = age;
        this.address = address;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    @Override
    public Object clone() {
        Student stu = null;
        try{
            stu = (Student)super.clone();
        }catch(CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return stu;
    }
}
public class Test {
    public static void main(String[] args) {
        Address addr = new Address();
        addr.setAdd("杭州市");
        Student student1 = new Student();
        student1.setAge(12);
        student1.setAddress(addr);
        Student student2 = (Student)student1.clone();
        student1.setAge(30);
        Address addr2 = new Address();
        addr.setAdd("北京");
        student1.setAddress(addr2);
        System.out.println("学生1:" + student1.getAge()+"地址:"+student1.getAddress().getAdd());
        System.out.println("学生2:" + student2.getAge()+"地址:"+student2.getAddress().getAdd());
    }
}

student1在赋值年龄12和地址为杭州之后clone创建student2 ,然后更改student1的值是不会影响student2 的值的,但是student2 当中address的add更改了,并且student1的地址没有了
在这里插入图片描述
因为上述Address没有实现Cloneable接口没有重写clone()方法

更改Address类

package cn.itbluebox.springbootactuator;

class Address implements Cloneable {
    private String add;

    public Address() {
    }

    public Address(String add) {
        this.add = add;
    }

    public String getAdd() {
        return add;
    }

    public void setAdd(String add) {
        this.add = add;
    }

    @Override
    public Object clone() {
        Address addr = null;
        try {
            addr = (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return addr;
    }
}

class Student implements Cloneable {
    private int age;
    private Address address;

    public Student() {
    }

    public Student(int age, Address address) {
        this.age = age;
        this.address = address;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public Object clone() {
        Student stu = null;
        try {
            stu = (Student) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        stu.address = (Address)address.clone();   //深度复制
        return stu;
    }
}

public class Test {
    public static void main(String[] args) {
        Address addr = new Address();
        addr.setAdd("杭州市");
        Student stu1 = new Student();
        stu1.setAge(123);
        stu1.setAddress(addr);

        Student stu2 = (Student)stu1.clone();
        System.out.println("学生1:" + stu1.getAge() + ",地址:" + stu1.getAddress().getAdd());
        System.out.println("学生2:" + stu2.getAge() + ",地址:" + stu2.getAddress().getAdd());

        addr.setAdd("西湖区");
        System.out.println("学生1:" + stu1.getAge() + ",地址:" + stu1.getAddress().getAdd());
        System.out.println("学生2:" + stu2.getAge() + ",地址:" + stu2.getAddress().getAdd());
    }
}

在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:20:29  更:2021-11-09 19:20:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:09:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码