java基础学习之小知识点
1.代码块
解释: { } 之间的就是代码块。
分类
-
局部代码块(方法中) :限定变量的生命周期,{}内的变量出了{},即不可访问;
-
构造代码块(类中方法外):每创建依次对象就会执行一次,优先于构造方法执行;
-
静态代码块(类中方法外,static修饰):随着类的加载而加载,且只执行一次。作用为给类进行初始化,一般用来加载驱动。
注:static{ } 优先于main方法执行。
class Fu {
static {
System.out.println("静态代码块Fu");
}
{
System.out.println("构造代码块Fu");
}
public Fu() {
System.out.println("构造方法Fu");
}
}
class Zi {
static {
System.out.println("静态代码块Zi");
}
{
System.out.println("构造代码块Zi");
}
public Zi() {
//默认super(); 见下一知识点
System.out.println("构造方法Zi");
}
}
执行 Zi z = new Zi(); 得结果如下:
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi
说明:1.类加载时加载静态代码块;2.根据分层初始化规则,先加载父类构造方法,但发现有构造代码块,故父构造代码块->父构造方法;然后子构造代码块->子构造方法
2.super和this的注意点
1.this调用父类成员:this.xx调用时,本类中没有xx成员方法或者xx成员变量时,调用父类的xx成员方法或者xx成员变量。
2.构造方法默认super():任何类的构造方法默认含"super();",最高级类为Object;
3.重载(overload)和重写(override)
重载和重写的比较
—— | 重载(overload) | 重写(override) |
---|---|---|
代码位置 | 类内 | 父类和子类之间 |
方法声明 | 方法名相同,参数不同(参数名;参数类型;参数顺序),方法体不同;与返回值无关 | 子类方法名和父类方法名完全相同,方法体不同; |
场景 | 不同参数不同调用结果,如:求图形面积,三角形两个参数,梯形三个参数 | 子类需要父类的功能,而功能主体子类有自己特有的内容时 |
补充 | 重写后,将用父类的方法时用 “super.方法()” 调用 |
一直重写重载傻傻分不清,记录下来方便以后温习。
4.final修饰符
final指的是最终的。
- 被final修饰的变量,变成常量,只能被赋值一次。
----常和public static一起用,实现“类名.被final修饰的变量”调用模式- 被final修饰的方法,不能被重写
- 被final修饰的类,不能被继承
注意点:
基本类型:值不能被改变
引用类型:地址值不能被改变(不能再次引用对象),但对象中的属性可以改变
对此验证,假设有如下类:
final class Final {
int x=1;
public void print() {
System.out.println(x);
}
}
调用可得:
Final f = new Final();
f = new Final(); //报错
f.x = 2; //没问题
f.print(); //得到输出:2
5.多态中的成员访问特点
多态的前提是:1.有继承关系;2.有方法重写;3.要有上转型
- 只有动态成员方法动态绑定,即编译看左边(父类),运行看右边(子类);
- 其他编译运行都看左边(父类)。
成员变量的调用
- 编译看左边(父类),运行看左边(父类)
class Demo_Polymorphic {
public static void main(String[] args) {
Father f = new Son();
System.out.println(f.num);
Son s = new Son();
System.out.println(s.num);
}
class Father {
int num = 10;
}
class Son extends Father {
int num = 20;
}
这段程序的内存图如下:
结论:
Father 类型的变量智能看到super 部分的成员,即得num=10;
Son类型的变量可以看到this范围内的所有成员,依据就近原则,取得num=20.
成员方法的调用
- 编译看左边(父类),运行看右边(子类)
- 即动态绑定
class Demo_Polymorphic {
public static void main(String[] args) {
Father f = new Son();
f.print();
}
}
class Father {
int num = 10;
public void print(){ //父类没有被调用方法时,编译将通不过
System.out.println(num);
}
}
class Son extends Father {
int num = 20;
public void print(){
System.out.println(num);
}
}
编译时看父类有没有print方法,内存图如下:
运行时看子类有没有print方法,内存图如下:
静态成员方法的调用
- 编译看左边(父类),运行看左边(父类)
不存在 “动态绑定”
Father f = new Son();
f.staticMethod(); //由于静态,相当于 Father.staticMathod();
6.多态+instanceof关键字
上转型和下转型
上转型:父类引用指向子类对象
下转型:将上转型对象转回子类对象
多态适用场景
用作参数的时候用多态最佳,这样扩展性好
开发中很少在创建对象是用父类引用指向子类对象,直接创建子类对象,多余且不能访问子类特有属性和行为
举个小例子:
class AnimalGames {
public static void main(String[] args) {
movement(new Cat());
movement(new Pig());
}
//多一种动物不需要多写movement方法,而是增加方法内逻辑分支,拓展性强。
//参数上转型,相当于Animal a = new Cat();
public static void movement(Animal a){
if(a instanceof Cat){ //判断引用a是否输入Cat数据类型
Cat c = (Cat)a; //此处下转型,若只用到父类共性方法,无需下转
c.eat();
c.catchMouse(); //子类特有,下转后才能调用
}else if(a instanceof Pig){
Pig p = (Pig)a;
p.eat();
p.sleep();
}
}
}
class Animal {
public void eat(){
System.out.println("动物吃");
}
}
class Cat extends Animal {
public void eat(){
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
class Pig extends Animal {
public void eat(){
System.out.println("猪吃饲料");
}
public void sleep(){
System.out.println("猪睡懒觉");
}
}
输出结果为:
猫吃鱼
猫抓老鼠
猪吃饲料
猪睡懒觉
心得:
总觉得这段时间将会是退休前最空闲的一段时间了。
希望能够在这段时间好好地沉下心来钻一钻技术基础,更重要的是希望能够更沉得下心,好好归零,做好规划,饱含憧憬和期待地走向下一程!
定个目标,勤写博客,保持学习惯性。
另外不得不说markdown真是好用,深得我心~