面向对象进阶
前言
接上期文章:JavaSE学习心得(基础语法篇)
教程链接:黑马程序员Java零基础视频教程_上部(Java入门,含斯坦福大学练习题+力扣算法题和大厂java面试题)_哔哩哔哩_bilibili
本期分享面向对象部分
面向对象基础
成员变量和局部变量
对象的成员变量的默认值
举例:
构造地址类
构造学生类:成员变量包含int类型、String类型、数组类型、Address类型
创建对象并测试
输出结果
JavaBean类
先写出所有成员变量并用private修饰,后续操作有两个方法
法一:快捷键
Alt + insert或Alt + Fn + insert
法二:安装插件
此外在写好构造方法后创建对象时Ctrl+p可以提示参数。
内存图
这里栈内存中s1先调用study方法后又出栈了,然后s2才调用
stu1 = null;
将 stu1
的引用置为空,但不影响 stu2
以及其所指向的对象。
从JDK8开始,取消方法区,新增元空间。把原来方法区的多种功能进行拆分,有的功能放到了堆中,有的功能放到了元空间中。
键盘录入
第一套体系:
nextInt();接收整数
nextDouble();接收小数
next();接收字符串
遇到空格,制表符,回车就停止接受。这些符号后面的数据就不会接受了
第二套体系:
nextLine();接收字符串可以接收空格,制表符,遇到回车才停止接受数据
弊端:先用nextInt,再用nextLine会导致下面的nextLine接受不到数据 ,所以键盘录入的两套体系不能混用的
把上一个回车当成录入了
字符串
字符串的内容是不会发生改变的,它的对象在创建后不能被更改。
三个对象
两个对象
创建String对象
法一:直接赋值
法二:new
内存模型
字符串比较
equals
这样就直接比内容不比地址值
遍历字符串
用到的方法:
正序遍历快捷键:fori
倒叙遍历快捷键:forr
手机号屏蔽
下图截取的是前三位和后四位
敏感词替换
StringBuilder
构造方法
常用方法
其中前两个返回对象本身
链式编程
Stringjoiner
构造方法
成员方法
扩展底层原理
字符串拼接的底层原理
字符串拼接的时候,如果有变量:
JDK8以前:系统底层会自动创建一个StringBuilder对象,然后再调用其append方法完成拼接。拼接后,再调用其toString方法转换为String类型,而toString方法的底层是直接new了一个字符串对象IDK8版本:系统会预估要字符串拼接之后的总大小,把要拼接的内容都放在数组中,此时也是产生一个新的字符串。
两道例题:
StringBuilder源码分析
默认创建一个长度为16的字节数组
添加的内容长度小于16,直接存
添加的内容大于16会扩容(原来的容量*2+2)
如果扩容之后还不够,以实际长度为准
ArrayList
成员方法
包装类
集合存基本数据类型时<>中填的是对应的包装类
面向对象进阶
静态
静态变量是随着类的加载而加载的,优先于对象出现的
main方法中还没写第一行代码时,静态区就已经随Student类的加载而有了teacherName变量,但初始值位null
静态方法中,只能访问静态。
非静态方法可以访问所有。
静态方法中没有this关键字
工具类
直接看例子:
继承
能继承的内容
继承成员方法
就近原则
方法重写
1.重写方法的名称、形参列表必须与父类中的一致。
2.子类重写父类方法时,访问权限子类必须大于等于父类
3.子类重写父类方法时,返回值类型子类必须小于等于父类
4.建议:重写的方法尽量和父类保持一致。
5.只有被添加到虚方法表中的方法才能被重写
构造方法的访问特点
子类不会继承父类中的构造方法。子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化。子类不管是无参还是有参构造方法都会先调用父类的无参构造方法,子类构造方法第一行语句默认都是:sùper(),不写也存在,且必须在第一行。
虽然不能重写父类构造方法,但子类的有参构造的参数内容和父类有着包含关系,可以这样构造
重写成员方法也是同理
多态
调用成员变量和成员方法的编译运行不一样
多态的运用
说明:老师、学生、管理员都继承了Person类且重写了show方法
多态的弊端
解决方案
包
使用同一个包中的类时,不需要导包。
使用java.lang包中的类时,不需要导包。
其他情况都需要导包
如果同时使用两个包中的同名类,需要用全类名。
final
修饰方法 表明该方法是最终方法,不能被重写
修饰类 表明该类是最终类,不能被继承
修饰变量 叫做常量,只能被赋值一次
常量的命名规范 :
单个单词:全部大写
多个单词:全部大写,单词之间用下划线隔开
final修饰的变量是基本类型:那么变量存储的数据值不能发生改变。
final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,对象内部的可以改变
举例:比如创建了一个学生对象,可以去改这个对象的姓名,年龄等,但不能又让这个对象=new students(); 创建了一个数组,可以改它arr[0]、arr[1]这些的值,但不能让arr重新指向另一个地址值
权限修饰符
代码块
左边局部代码块:局部代码块中定义的,只能在该块内部使用,否则编译报错
右边构造代码块
静态代码块:在类加载的时候,做一些数据初始化的时候使用。
抽象方法
如果一个类中存在抽象方法,那么该类就必须声明为抽象类,但抽象类中不一定有抽象方法,抽象类不能用来创建对象,但可以有构造方法直接给子类用,子类要么重写所有的抽象方法,要么也为抽象类。
都是Alt+回车
接口
接口不能实例化,接口的子类(实现类)要么重写接口中的所有抽象方法要么是抽象类
注意1:接口和类的实现关系,可以单实现,也可以多实现。
public class 类名 implements 接口名1,接口名2 {}注意2:实现类还可以在继承一个类的同时实现多个接口。
public class 类名 extends 父类implements 接口名1,接口名2 {}
接口中的成员变量只能是常量
默认修饰符:public static final ,不写自带
成员方法只能是抽象方法
默认修饰符:public abstract,不写自带
JDK8以后允许在接口中定义默认方法,需要使用关键字 default 修饰
格式:public default 返回值类型 方法名(参数列表){}
默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字public可以省略,default不能省略
如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
JDK8以后允许在接口中定义定义静态方法,需要用static修饰
格式:public static 返回值类型 方法名(参数列表){}
静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
public可以省略,static不能省略
静态方法不可以被重写,但可以在实现类中有重名方法
接口和类的关系
内部类
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
除了匿名内部类,其他了解即可
成员内部类
内部类获取外部类成员变量
静态内部类
静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象。
静态内部类创建对象的格式和普通成员内部类不一样了
局部内部类
将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。
外界是无法直接使用局部内部类,需要在方法内部创建对象并使用。
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
匿名内部类
其他补充知识
跳出多层循环
可以先调用还没写的方法,再Alt+回车生成方法,这个快捷键功能很多,包括导包等。
字符数组存储字符串
String str=new String("hello");
char[] ch=str.toCharArray();
System.out.println(ch);//hello
System.out.println(ch.toString());//[C@4eec7777
System.out.println(Arrays.toString(ch));//[h, e, l, l, o]
当数组中包含字符时,Java 允许将其作为字符串处理,而int、double这些类型的数组包括String字符串数组第一个输出也会是地址值