javaSE基础复习之面向对象(多态,内部类,java面试常见笔试题

//创建对象1:

Pig one = new Pig(); //猪是猪

//创建地下2:

Animal two = new Pig(); //猪是动物 is a

多态的前提条件

(1)父子关系 继承或者实现关系

(2)方法重写

(3)左父右子 父类引用指向子类对象 Animal two = new Pig();

第02节 快速入门

案例代码

父类

//多态快速入门 父类

public class FuLei {

String name = “王健林”;

int ageFu = 60;

public void say(){

System.out.println(“给你一个小目标”);

}

public void methodFu(){

System.out.println(“我是BABA”);

}

}

子类

//多态快速入门 子类

public class ZiLei extends FuLei{

String name = “王思聪”;

int ageZi = 30;

public void say(){

System.out.println(“你们都没我有钱”);

}

public void methodZi(){

System.out.println(“我是儿子”);

}

}

测试类

//测试类

public class Test {

public static void main(String[] args) {

//采用多态的形式创建对象。左父右子

FuLei ooo = new ZiLei();

//调用成员变量

System.out.println(ooo.ageFu); //60

//System.out.println(ooo.ageZi); //报错了

System.out.println(ooo.name); //王健林

//成员变量的结论1: 看等号左边是谁,则优先使用谁,没有则向上找

//成员变量的结论2: 编译看左边,运行看左边

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

//调用成员方法

ooo.methodFu(); //我是BABA

//ooo.methodZi(); //报错了

ooo.say(); //你们都没我有钱

//成员方法的结论1: 看等号右边是谁,则优先使用谁,没有则向上找

//成员方法的结论2: 编译看左边,运行看右边。

}

}

//多态的缺点: 无法访问子类特有的成员(成员变量和成员方法)

效果图

在这里插入图片描述

第03节 两种转型

基础理论

  1. 向上转型

A. 含义: 将子类对象看做父类的对象(儿子看做父亲)

B. 举例: Animal aa = new Pig(); //猪是动物

  1. 向下转型

A. 含义: 将父类对象看做儿子的对象(父亲看做儿子)

B. 举例: Pig pp = (Pig)aa; //动物是猪

C. 应用: 多态的缺点是无法访问子类特有的成员,就需要使用向下转型,得到子类对象,再去调用特有成员

注意事项

在向下转型的过程当中,需要注意异常: ClassCastException 类型转换异常。

解释: 在向上转型的过程当中,原本是什么类型,转换的时候,就要变成什么类型,不要变成他的兄弟。

效果图

在这里插入图片描述

如何解决问题?

解决类型转换异常的问题 ClassCastException

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

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.in

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

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

NoStatic(); //内部类…非静态方法

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

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 类名称/接口名称(参数){

//…方法…

};

由来

动物的接口

//动物的接口

@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++调用的是操作系统底层,例如声卡)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值