查漏补缺:
变量:
根据变量声明的位置不同 将变量分为局部变量 成员变量(实例变量 、 全局变量)
局部变量:声明在方法中的 或者是代码块中的变量 称之为局部变量(方法中的形参也是隶属于方法的局部变量)
只能在当前方法中有效 出了这个方法无效
局部变量 要在声明且赋值 才能够正常使用
代码块:
一组大括号括起来的就称之为代码块 {}
声明在方法中的代码块称之为 局部代码块: 作用:减少变量的生命周期 降低系统的内存开销
成员变量:
定义在类中 方法外 作用范围在整个类中有效,存在默认值:
byte short int long ( 默认为 0)
float double (默认为 0.0)
char (默认为 '\u0000' 空格)
boolean (默认为 false)
引用 (默认为 null )
构造器:
特点:
通过new关键词调用构造器可以产生当前类的实例/对象
构造器的注意事项:
1、构造器方法不需要些返回值类型
2、方法的名称和类名保持一致
3、无需在方法内部显式的返回当前对象
4、如果在一个类中不写构造器 默认存在一个 空构造器 无参构造器
5、如果在类中显式声明一个构造器 那么默认的构造器就不存在了 (建议 写类的时候一定要保证空构造器的存在)
6、构造器可以重载
this:(当前对象)
this.
可省略:
不可省略:
出现同名变量,this. 用来区分同名变量的
this() 调用构造器的
在类中无法通过构造器的名称直接调用构造器
注意点: this()必须要在构造器的首行编写
继承:
子承父业
作用: 提高了代码的复用性
使用: 子类 extends 父类
注意: 子类可以使用父类中定义的属性以及方法 子类中也可以定义自己独有的功能和属性
java中只支持单继承 一个类只能有一个直接父类
思考: 复用性没有那么强 ,为什么还需要继承? 维护的一种关系-> is a
答: 维护了逻辑关系 并且可以让我们更好的通过面向对象去梳理系统之间的关系(因为java只能继承一个类,所以复用性不是很强,那为什么它还是面向对象的三大特征之一呢?在实际运用中我们主要使用继承去维护一种逻辑关系。)
面试问题: A-> B 后期迭代过程中发现A->C更优 解决办法?
目前自己的想法为:采用组合技术,在B中实例化C
一个类没有显式的继承其他类 那么默认父类是Object 我们讲Object称之为所有类的超类 父类 基类
方法重写:
父类中的功能不满足子类的需要 子类重写
super: 代指父类对象
super.
可省略:
不可省略:区分子类和父类中中的同名方法/同名变量
super():调用父类构造器的
默认调用父类的空构造器, super()必须要在构造器的首行
super()和this() 如何都能发挥作用?
千万注意super()和this()不能同时出现 有super就没有this 有this就没有super。
如何都发挥作用:保留this() 通过this调用的构造器中 持有一个super的指向。
包:
为什么需要包呢?用于区分类的
一个类中顶头写 package 声明当前类从属于那个包
导包:
为什么要导包? java中是以类为单位的 如何区分一个类,通过全限定名 包名.类名
通过import关键词 + 全限定名 在声明类前 添加这行代码
如何导入同名类?
只能有一个类通过导包方式导入,其他同名的类 通过全限定名操作
com.公司名.oop.Scanner sc = new com.公司名.oop.Scanner(); (如果已经引入系统Scanner对应的包,可以通过此种方式引入自己写的类)
如何静态导入?(java1.5之后加入)
import static java.lang.Math.PI;
封装:
4个关键词
本类 同包子类 同包 异包子类 异包
public √ √ √ √ √
protected √ √ √ √ ×
默认的 √ √ √ × ×
private √ × × × ×
封装: 调用者而言: 降低了调用的复杂度 降低了学习成本
被调用者而言:增加了被调用者安全系数 维护内部系统的稳定性
继承在一定程度上了破坏了封装性
多态 : 多种形态
1、继承关系
2、子类要重写父类的方法
3、父类变量指向了子类对象
static:
public class Test05 {
public static void main(String[] args) {
F f=new F();
F f1=new F();
}
}
class F{
static{
System.out.println("静态代码块。。");
}
{
System.out.println("初始化块。。");
}
public F(){
this(4);
System.out.println("无参数的构造方法");
}
public F(int num){
System.out.println("带参数的构造器。。");
}
}
静态代码块。。
初始化块。。
带参数的构造器。。
无参数的构造方法
初始化块。。
带参数的构造器。。
无参数的构造方法
总结分析:
1、一个类中的静态代码块是最先加载的,但是只会加载一次
2、初始化代码块会优先于构造器执行,编译阶段初始化代码块会存在于构造器的首行(我们可以使用反编译工具对编译代码进行查看)
3、static修饰的成员是隶属于类的,是类和对象共享的
4、以上代码无参数的构造器会调用带参数的构造器,this();需要放在无参构造器的首行。而编译器编译时是将初始化代码块放在构造器的首行,此时会不会冲突呢?情况是这样的:编译器编译时,编译到this();语句之后,知道程序会执行带参数的构造器,于是将初始化的代码块放在带参数的构造器的首行。
public class Test05 {
public static void main(String[] args) {
System.out.println(S.num);
System.out.println("====================");
System.out.println(S.number);
}
}
class S{
static final int num=10;
static final int number=(int)(Math.random()*10);
static{
System.out.println("我被执行了。。");
}
}
}
10
====================
我被执行了。。
9
总结分析:
调用静态内容类会不会加载?
1、如果调用的静态内容是一个常量值,常量值是一个字面值,那么该常量会在编译期间确定其值,访问时就不会导致类加载(常量值得意思就是该内容被final修饰了)。(编译期静态常量不会导致类加载)
2、如果调用的静态内容不是一个字面常量值,那么该常量会在加载时确定,调用就会导致类加载。(非编译期静态常量会导致类加载)
请解释:可以在非static方法中使用static内容 但是不能在static内容中使用非static内容
因为静态内容会优先于非静态的内容加载,静态内容不能去使用还没有加载出来的内容。
请问:现有类还是先有对象
答:1、对于编码来说:先有类再有对象
2、对于构建来说:先有对象再抽象出类
注意:编译看左边 运行看右边 动态联编
equals:
如何判断字符串是不是空串? "".equals(str)
String equals()方法源码分析:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
//此处为什么不在原字符串的基础上进行比较?
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
解答以上问题:
按照一贯逻辑思维,会直接在原字符数组上进行比较。源码中采用先赋值给局部变量,再进行比较的好处是:value值属于全局变量,生命周期更长,局部变量的生命周期更短相对于全局变量。现在赋值给局部变量来做,如果value在别处不再有引用,那么gc就会自动对他进行回收,节约了内存空间的消耗。
问题:为什么非静态内部类中不能有static成员变量却可以有static final 属性的编译期常量?
参考文献:https://blog.csdn.net/wuchangi/article/details/79182850