一. 代码块
代码块分为:局部代码块、动态代码块、静态代码块
局部代码块:声明在方法中的代码块,执行时机与声明位置相关, 提前释放变量。(了解)
动态代码块:又称构造代码块或实例代码块,声明在类体中的代码块,创建对象时自动执行一次,每创建一个对象就
执行一次动态代码块。初始化工作。(了解)
静态代码块:使用static关键字修饰的动态代码块,在类加载时自动执行,并只执行一次。(记住)
1.1 局部代码块(定义在方法中的,用来限制变量的作用范围)
- 局部代码块是定义在方法或语句中
- 以”{}”划定的代码区域,此时只需要关注作用域的不同即可 方法和类都是以代码块的方式划定边界的
class Demo{
public static void main(String[] args) {
{
int x = 1;
System.out.println("普通代码块" + x);
}
int x = 99;
System.out.println("代码块之外" + x);
}
}
out:(输出结果)
普通代码块1
代码块之外99
1.2 构造代码块(定义在类中方法外,用来给对象中的成员初始化赋值)
- 构造代码块是定义在类中成员位置的代码块
- 优先于构造方法执行,构造代码块用于执行所有对象均需要的初始化动作 每创建一个对象均会执行一次构造代码块。
1.3 静态代码块(定义在类中方法外,用来给类的静态成员初始化赋值)
静态代码块是定义在成员位置,使用static修饰的代码块。
- 它优先于主方法执行、优先于构造代码块执行,当以任意形式第一次使用到该类时执行。
- 该类不管创建多少对象,静态代码块只执行一次。
- 可用于给静态变量赋值,用来给类进行初始化。
二. 继承
2.1 继承的概念
继承 :就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接
访问父类中的非私有的属性和行为。
好处
1. 提高代码的复用性。
2. 类与类之间产生了关系,是多态的前提。
2.2 继承的使用
使用extends关键实现两个类的继承关系
被继承的类:父类,超类,基类
继承的类:子类,派生类
继承符合: is a 关系
public class FatherClass{
//属性
//方法
}
public class ChildClass extends FatherClass {
//属性
//方法
}
1)私有成员:私有成员不能被子类继承
2)构造方法:父类中的构造方法不能被子类继承,但是会在子类的构造方法中调用(子类的构造
方法中默认第一条语句是调用父类的默认构造方法)
特点
1)单继承:一个子类只能有一个父类,一个父类可以有多个子类
2)传递性:继承具有传递性
2.3 super关键字
super关键字:用法和this类似
1)super.属性:表示访问父类中的属性,当子类中定义了与父类同名的属性时,若想在子类中访
问父类的同名属性,需要使用super.属性访问
2)super.方法:表示调用父类中的方法,在子类中需要调用父类中没有被重写的方法时,需要使
用super.方法调用
3)super():表示调用父类的构造方法,注意:super()必须是子类构造方法中第一条语句
子类中构造方法默认第一条语句会调用父类的无参数构造方法super(),也可以手动调用父类中带
参数的构造方法
class Animal {
public void eat() {
System.out.println("animal : eat");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("cat : eat");
}
public void eatTest() {
this.eat(); // this 调用本类的方法
super.eat(); // super 调用父类的方法
}
}
public class ExtendsDemo08 {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Cat c = new Cat();
c.eatTest();
}
}
输出结果为:
animal : eat
cat : eat
animal : eat
2.4 成员方法重名 ——重写(Override)
如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。
- 方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效 果,也称为重写或者复写。声明不变,重新实现。
class Fu {
public void show() {
System.out.println("Fu show");
}
}
class Zi extends Fu {
//子类重写了父类的show方法
public void show() {
System.out.println("Zi show");
}
}
public class ExtendsDemo05{
public static void main(String[] args) {
Zi z = new Zi();
// 子类中有show方法,只执行重写后的show方法
z.show(); // Zi show
}
}
注意:
- 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
- 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。
- 我们通常都只会用到方法重写,而忽略了属性重写
那么属性和方法都可以重写?
Java方法重写是子类重写父类同名的方法,子类方法覆盖了父类的方法。而对于属性,子类不会覆盖父类同名的属性。
如果子类没有定义属性,子类会继承最近父类的属性。
如果创建子类对象后,父类和子类对象都会保存一份自己的属性,子类对象引用向上转型为父类对象引用,父类对象引用调用的是子类重写的方法,调用的属性仍然是父类的属性。
class Parent{
public String name = "Parent";
public void printName(){
System.out.println("Parent printName()");
}
}
public class Child extends Parent{
public String name = "Child";
public void printName(){
System.out.println("Child printName()");
}
public static void main(String[] args) {
Child child = new Child();
Parent parent = child; //子类向上转型为父类
parent.printName(); //调用的是子类的方法 Child printName()
System.out.println(child.name); //子类的属性 Child
System.out.println(parent.name); //父类的属性 Parent
}
}
2.5 继承后的特点——构造方法
当类之间产生了关系,其中各类中的构造方法,又产生了哪些影响呢?
首先我们要回忆两个事情,构造方法的定义格式和作用。
- 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
- 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构
造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。代码如下:
class Fu {
private int n;
Fu(){
System.out.println("Fu()");
}
}
class Zi extends Fu {
Zi(){
// super(),调用父类构造方法
super();
System.out.println("Zi()");
}
}
public class ExtendsDemo07{
public static void main (String args[]){
Zi zi = new Zi();
}
}
输出结果:
Fu()
Zi()
在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空
间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法。
一定要区分方法重写和方法重载的区别
方法的重载:Overload,在同一个类中,方法名相同,参数类别不同,互为重载方法。
方法的重写:Override,在继承过程中,在子类中重写父类中继承来的方法,方法名、参数列
表、返回值必须相同,访问权限不能比父类严格。