javaSE基础复习之面向对象(多态,内部类,mysql主从搭建教程

//判断当前的对象 是否来自于 类

if(对象名称 instanceof 类名称){

//向下转型的代码…

//调用子类特有成员的代码…

}

举例说明

//判断 对象ooo 他的类型是否是 来自于 Brother 类

if(ooo instanceof Brother){

//进行向下转型

Brother bbb = (Brother) ooo;

//调用子类特有的成员

System.out.println(bbb.ageZi);

bbb.methodBro();

}

第04节 指鹿为马

案例代码

动物接口

//动物接口

public interface Animal {

//吃

public abstract void eat();

}

马类

//马类

public class Ma implements Animal{

@Override

public void eat() {

System.out.println(“马吃草…”);

}

public void pao(){

System.out.println(“马儿跑.”);

}

}

鹿类

//鹿类

public class Lu implements Animal{

@Override

public void eat() {

System.out.println(“鹿吃艹”);

}

public void tiao(){

System.out.println(“鹿儿跳.”);

}

}

测试类

//测试类

public class Test {

public static void main(String[] args) {

//创建对象

Ma make = new Ma();

use(make);

//直接调用方法(匿名对象的写法)

use(new Lu());

}

// 一个方法,既可以接收马的对象, 又可以接收鹿的对象

// 这个方法的参数应该怎么写呢?

// 这里就可以写 父类或者是父接口,采用多态传参

public static void use(Animal aa){ //Animal aa = new Ma();

//调用方法【共性方法父亲调用】

aa.eat();

//调用方法【如果想要访问特有的,应该向下转型】

//如果说 aa对象来自于 Ma类。 则向下转型成为Ma

if (aa instanceof Ma){

//向下转型

Ma make = (Ma) aa;

//调用子类特有方法

make.pao();

}

//再次判断 如果说 aa对象来自于 Lu类。

if (aa instanceof Lu){

//向下转型

Lu luhan = (Lu) aa;

//调用子类特有方法

luhan.tiao();

}

}

}

第05节 优点缺点

优点

  1. 提高代码的扩展性

解释: 如果说,我们将方法的参数定义为 父类或者是父接口。那么就可以传递 子类或者实现类。

以前的写法是 每一个子类都需要作为方法的参数,可能写很多的方法。

  1. 提高代码的复用性

解释:根据多态的前提条件,有父子关系。在继承的优点当中,就是提高代码的复用性。

我们将共性的代码交给父类。共性的方法交给父接口,这类写法,可以提高复用性。

父亲里面定义一份,多个儿子都可以使用。

缺点

无法访问子类 特有的成员(成员变量和成员方法)

如果想要访问,则需要判断和转型

第二章 内部类


第01节 基础理论

什么是内部类呢?

内部类就是说在一个类大括号里面,包含着另外一个类。

注意: 这里的包含关系,不是继承关系。(继承关系存在 is A 关系,子类可以看做父类)

生活实例:

身体和心脏的关系,就是一种包含关系。 在身体里面包含的有心脏。

内部类的分类有哪些?

(1)成员内部类。独立的分支:静态成员内部类

(2)局部内部类。独立的分支:匿名内部类

内部类的应用场景?什么时候会使用内部类

以前在学习 界面编程当中,有点击事件。(JavaScript 讲过点击的效果) 这里就会使用到内部类。

在 Android 编程当中使用较多。

有些 Java底层源代码当中,会使用到内部类。

第02节 成员内部类

位置

在一个类的成员变量或者成员方法的地方,编写类。(类当中,方法外)

代码

外部类和内部类

//身体(外部类)

public class Body {

String name = “身体”;

private int age = 18;

public void exercise(){

System.out.println(“身体成员方法…锻炼”);

}

//-------------------

class Heart{

String name = “心脏”;

public void jump(){

System.out.println(“心脏跳…蹦蹦蹦…”);

}

public void show(){

String name = “嘿嘿嘿”;

System.out.println(name); //嘿嘿嘿

System.out.println(this.name); //心脏

System.out.println(Body.this.name); //身体

System.out.println(Body.this.age); //18

}

}

//-------------------

}

测试类

//测试类

public class Test {

public static void main(String[] args) {

//如果想要创建,内部类的对象,应该怎么使用呢?

//公式是: 外.内

Body.Heart bh = new Body().new Heart();

//调用成员变量和成员方法

System.out.println(bh.name); //心脏

bh.jump(); //心脏跳…蹦蹦蹦…

System.out.println("--------");

bh.show();

}

}

第03节 静态成员内部类

理论

  1. 位置: 类中方法外的类。保证他是一个成员内部类

  2. 添加 static 关键字。

  3. 效果: 可以直接使用类名称打点调用

代码

外部类和内部类

//外部类

@SuppressWarnings(“all”)

public class Outer {

//静态变量

static String name = “外部类”;

//内部类:静态内部类

static class Inner {

String name = “内部类”;

public void inNoStatic() {

System.out.println(“内部类…非静态方法”);

}

public static void inYesStatic() {

System.out.println(“内部类…静态方法”);

}

}

}

测试类

public class Test {

public static void main(String[] args) {

//创建对象。访问非静态方法

Outer.Inner one = new Outer.Inner();

//调用方法

one.inNoStatic(); //内部类…非静态方法

//如果想要调用静态内部类当中的静态方法。

Outer.Inner.inYesStatic(); //内部类…静态方法

}

}

第04节 局部内部类

理论

什么是局部内部类啊?

  1. 位置:

定义在方法当中的类,叫做局部内部类。

  1. 范围:

只能在方法里面使用,出了方法,无法使用。

代码

外部类和内部类

//外部类:演示局部内部类

@SuppressWarnings(“all”)

public class Outer {

String name = “外部类”;

//成员方法

public void show() {

//局部变量

int age = 18;

//打印输出

System.out.println(age);

}

//成员方法

public void method() {

//-------------------

class Inner {

String name = “内部类”;

public void say() {

System.out.println(“我是局部内部类成员方法”);

}

}

//-------------------

//创建对象

Inner iii = new Inner();

iii.say();

}

}

测试类

//测试类

public class Test {

public static void main(String[] args) {

//只能创建外部类的对象

Outer ooo = new Outer();

//调用方法

ooo.method();

}

}

面试问题

在这里插入图片描述

第05节 匿名内部类

理论

  1. 介绍:

匿名内部类指的是没有名字的内部类,他是局部内部类的一种。

  1. 写法:

new 类名称/接口名称(参数){

//…方法…

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

};

由来

动物的接口

//动物的接口

@SuppressWarnings(“all”)

public interface Animal {

//吃的方法

public abstract void eat();

}

实现类

//实现类

@SuppressWarnings(“all”)

public class Dog implements Animal {

@Override

public void eat() {

System.out.println(“狗吃SHI”);

}

}

测试类

//测试类

public class Test {

//思考问题:我们能不能省略 实现类(Dog) 不写呢?

public static void main(String[] args) {

//版本1:原始的用法,创建实现类的对象,去调用方法

Dog one = new Dog();

one.eat(); //狗吃SHI

System.out.println("---------");

//版本2: 多态的写法,左父右子

Animal two = new Dog();

two.eat(); //狗吃SHI

System.out.println("--------");

//版本3: 匿名内部类的写法

Animal three = new Animal() {

@Override

public void eat() {

System.out.println(“狗吃SHISHI”);

}

};

three.eat();

}

}

应用场景

如果方法的参数写的是接口,传递的是接口的实现类。(匿名内部类他也是接口的实现类)

拓展点:反编译的指令 javap 类名称.class

在这里插入图片描述

接口代码

//定义接口

public interface Usb {

//定义抽象方法: 连接

public abstract void connect();

}

测试类

public class Test {

public static void main(String[] args) {

//直接调用方法

useUsb(new Usb() {

@Override

public void connect() {

System.out.println(“连接电脑”);

}

});

}

//定义一个使用USB接口的方法

public static void useUsb(Usb sb){

//调用方法

sb.connect();

}

}

//小结:

//如果我们方法的参数写的是接口或者是类

//那么传递参数的时候,写的是实现类或者是子类。(也可以是匿名内部类)

//本质上面来说,匿名内部类就是子类或者实现类。 也就是多态的用法

//反编译操作: javap 类名称.class

第三章 内存回收


第01节 内存管理

内存划分图区域

在这里插入图片描述

五个区域介绍

1、程序计数器

  1. 较小

程序计数器是一块较小的内存空间,它的作用是当前线程执行指向字节码的行号指示器。

简单一点说,就是指挥程序执行那一条指令。(分支、循环、跳转、异常)

  1. 线程私有

Java虚拟机的执行,是由多条线程轮流切换处理器的时间来执行,

在任何一个时刻当中,一个处理器只会执行一条指令。

那么每个线程,都会存在一个独立的程序计数器,各个线程之间的程序计数器,不会受到影响的,独立存储。

  1. 无异常

如果线程正在执行的是一个 Java的方法,这个计数器记录的是正在执行的虚拟机字节码地址。

如果正在执行的是 Native 形式的方法,则计数器的值记录为空 Undefined

此时此刻内存区域是唯一一个在 Java规范当中没有任何的 OutOfMemoryError 情况区域。

2、虚拟机栈

  1. 线程私有

与程序计数器一样,Java虚拟机栈也是线程私有的,他的生命周期与线程相同。

  1. 描述Java方法执行的内存模型

每个方法被执行的时候,都会同时创建一个栈帧(Stack Frame 栈帧是方法运行时的基础数据结构)

用于存储局部变量表、操作栈、动态链接、方法出口灯信息。

每个方法被调用直到执行完毕的整个过程,都会对应一个栈帧在虚拟机栈,从入栈到出栈的过程。

  1. 异常

在Java虚拟机当中,规定了下面的两种异常情况。

【1】StackOverflowError JVM规定了栈的最大深度,如果执行方法超过最大深度,则出现栈溢出

【2】OutOfMemoryError JVM在扩展时候,无法申请到足够的内存,则出现内存溢出

3、本地方法栈

  1. 为 native 服务

虚拟机栈是为 Java服务的

本地方法栈是为 native 方法服务的(native方法底层是C\C++调用的是操作系统底层,例如声卡)

  1. 异常

与虚拟机栈一样,本地方法栈也会抛出 StackOverflowError 和 OutOfMemoryError

4、Java堆

  1. 最大

对于大多数应用来说,Java堆是 Java虚拟机管理的内存当中,最大的一块

  1. 线程共享

Java堆是被所有线程共享的一块内存区域,在虚拟机启动的时候创建

  1. 存放实例

堆区域,唯一的目的就是存放对象的实例,几乎所有的对象实例,都是在这里分配。

另外说明:在Java虚拟机规范当中描述,所有的对象和数组都是在堆上面分配,

但是随着JIT编译器发展,在堆上分配的方式,渐渐地已经不再是那么的绝对了。

  1. GC

Java堆是垃圾收集器管理的主要区域。

如果从内存的回收的角度来看,现在收集器采用的是分代收集算法。在 Java的堆当中,细分为 新生代和老年代。

如果从内存分配的角度来看,线程共享的Java堆可以划分多个线程私有分配缓冲区。

不过,无论如何划分,都与存放内容无关,无论哪个区域,存储的都依然是对象实例。

进一步的划分,目的只是为了更好的回收内存,或者更快的分配内存。

5、方法区

方法区,存储的是已经被虚拟机加载的数据,他有以下三个特点:

  1. 线程共享。 方法区和Java堆一样,也是被各个线程共享的内存区域

  2. 存储数据类型。 类信息、常量、静态变量、即时编译器编译后的代码

  3. 异常。 如果系统定义太多的类,导致方法区溢出,虚拟机同样会出现内存溢出溢出 OutOfMemeryError

方法区,又可以划分成为两个区域:

  1. 运行时常量池。

存储的是编译期间生产的各类字面量和符号引用,这部分内容加载后会进入方法运行时常量池存放。

运行时常量池,受到方法区内存限制,当常量池无法申请到内存空间的时候,则出现 OutOfMemeryError

  1. 直接内存, 存在以下四个特点

A. 在虚拟机外的数据 (说明:直接内存,不是虚拟机当中的内容,而是虚拟机之外的内存)

B. 直接分配 (说明:在JDK1.4之后的NIO,引入通道 Channel 缓冲区Buffer,可以操作直接内存)

C. 受到设备内存大小限制 (说明:受到设备总大小限制,而不是Java堆大小限制)

D. 异常(说明:如果超过内存容量,也会出现 OutOfMemeryError)

第02节 垃圾回收

基础理论

对于 Java 而言,好处: 系统帮我们去控制垃圾回收的。(系统自动完成的,不由程序员控制)

对于 C++ 而言,不是这样的,他的垃圾需要手动清理。(程序员自己去控制)

一个对象生命周期

  1. 刚刚出世的阶段

  2. 青年期

  3. 老年期

配图

在这里插入图片描述

标记清除算法

在这里插入图片描述

说明

生活实例:

相当于先把货架上面的货物,标记记录下来,(有人买的、没人买的、空着的商品和位置记录)

然后再把没人买的商品统一的进行下架处理,这是垃圾收集器的 早期策略

工作原理:

  1. 标记所有需要回收的对象

  2. 标记完毕后,统一回收所有标记的对象

缺点:

  1. 效率低:

标记和清除的效率都不高

  1. 内存碎片:

标记清除后,会产生大量的不连续的内存碎片。

导致程序需要分配较大对象时,无法找到足够连续空间,不得不提前触发GC垃圾收集器

复制算法

在这里插入图片描述

说明

目的:

为了解决效率的问题,复制(copying)收集算法就出现了

工作原理:

  1. 将内存按照容量大小,划分成为大小相同的两个区域。(例如A区域和B区域)

  2. 每次使用A区域的时候,B区域空闲。

  3. 当A区域使用完毕之后,将存活的对象,复制到B区域当中,一次性清理掉A区域的内容。

  4. 这样的操作,每次都是回收半块内存,内存分配过程当中,无需考虑内存碎片的问题。

优点:

  1. 每次针对于半个内存区域进行内存的回收。

  2. 分配内存的过程当中不需要考虑内存碎片的复杂情况,只需要移动堆顶指针,按照顺序分配内存即可。

缺点:

  1. 浪费空间。把内存缩小一半用,太浪费空间。

  2. 有时候效率低。在对象存活率高的时候,需要进行较多的复杂操作,这时候,效率就低了。

标记整理算法

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值