JavaSE——Day8——代码块,继承,方法重写与方法重载的区别,final关键字

代码块

在Java中,使用{}括起来的代码被称为代码块。
代码块的分类,根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块

局部代码块:在方法中出现;限定变量生命周期,及早释放,提高内存利用率。

构造代码块:在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行。

静态代码块:在类中方法外出现,加上了static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。

A:看程序写结果

		class Student {
			static {
				System.out.println("Student 静态代码块");
			}
			
			{
				System.out.println("Student 构造代码块");
			} //构造代码块,优先于构造方法执行
              //每创建一次,构造代码块都要执行
			
			public Student() {
				System.out.println("Student 构造方法");
			}
		}

		class StudentDemo {
			static {
				System.out.println("StudentDemo的静态代码块");
			}
			
			public static void main(String[] args) {
				System.out.println("我是main方法");
				
				Student s1 = new Student();
				Student s2 = new Student();
			}
		}

输出:
StudentDemo的静态代码块
我是main方法
Student 静态代码块
Student 构造代码块
Student 构造方法
Student 构造代码块
Student 构造方法
	

分析:先找main()方法,在StudentDemo类中,按顺序朝下走:
1、先执行StudentDemo类中的静态代码块(只执行一次)——StudentDemo的静态代码块
2、再执行main()方法——我是main方法
3、创建s1对象,调用StudentL类,按顺序执行,先执行Student类中的静态代码块——Student 静态代码块,构造代码块优先于构造方法执行,——Student 构造代码块,最后执行构造方法——Student 构造方法
4、创建s2对象,同样调用Student类,不再执行静态代码块,构造代码块和构造方法依次执行——Student 构造代码块——Student 构造方法

输出:
StudentDemo的静态代码块
我是main方法
Student 静态代码块
Student 构造代码块
Student 构造方法
Student 构造代码块
Student 构造方法

继承

多个类中存在相同属性和行为时,将这些内容抽取到单独的一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。

语法

通过extends关键字可以实现类与类的继承。

class 子类名 extends 父类名 {}

单独的这个类称为父类,基类或者超类,这多个类可以称为子类或者派生类。

public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        // Teacher student = new Student(); 也可以创建学生对象
        student.teaEat();
        student.teaSleep();
    }
}

class Teacher {
    public void teaEat() {
        System.out.println("我要吃饭了");
    }

    public void teaSleep() {
        System.out.println("我要睡觉了");
    }
}

class Student extends Teacher {
}

这是一个简单的继承,学生类继承了老师类的方法,学会了吃饭和睡觉。

继承的好处
1、提高了代码的复用性。
2、提高了代码的维护性。
3、让类与类之间产生了关系,是多态的前提。
继承的弊端
类的耦合性增强了。

开发的原则是:高内聚,低耦合
耦合:类与类的关系
内聚:就是自己完成某件事情的能力

Java中类的继承特点

1、Java中只支持单继承,不支持多继承。有些语言是支持多继承的。
2、java支持多层继承(继承体系)

案例:创建一个动物类,实现两个方法:吃饭和睡觉,再分别创建狗类和猫类来继承动物类,再分别实现各自独有的方法;

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "大黄";
        dog.age = "2";
        dog.Eat();
        dog.Sleep();
        dog.action();

        Cat cat = new Cat();
        cat.name = "罗小黑";
        cat.age = "1";
        cat.Eat();
        cat.Sleep();
        cat.action();
    }
}

class Animal {
    int age;
    String name;

    public void Eat() {
        System.out.println("吃饭饭");
    }

    public void Sleep() {
        System.out.println("睡觉觉");
    }
}

class Dog extends Animal {
    public void action() {
        System.out.println("我能看门");
    }
}

class Cat extends Animal {
    public void action() {
        System.out.println("我能抓老鼠");
    }
}

继承的注意事项

1、子类只能继承父类所有非私有的成员(成员方法和成员变量)
2、子类不能继承父类的构造方法,但可以通过super关键字去访问父类构造方法
3、不要为了部分功能去继承。

父类的构造方法的作用其实是让子类完成对父类数据的初始化,子类要继承父类数据,有可能还要用父类的数据,如果父类没有先完成初始化,那么父类的数据子类就没法用。

什么时候使用继承?

继承其实体现的使用“is a”的关系。如果有两个类型A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。

继承中成员变量的关系

在子类中访问一个变量的查找顺序“就近原则”:
a、在子类的方法的局部范围找,有就调用
b、在子类的成员范围找,有就调用
c、在父类的成员范围中找,有就调用
d、如果还找不到,就报错

public class Test {
    public static void main(String[] args) {
        Son son = new Son();
        son.show(20);
    }
}

class Father {
    int age = 100;
}

class Son extends Father {
    int age = 50;

    public void show(int age) {
        System.out.println(age);   //20
        System.out.println(this.age);   //50
        System.out.println(super.age);   //100
    }
}

super关键字

子类局部范围访问父类成员变量。

this 和 super 的区别

this : 代表的是本类对象的引用
super : 代表的是父类存储空间的标识(可以理解成父类的引用,可以操作父类的成员)
this 代表子类的一个引用,你可以理解为子类的一个对象,谁调用我,我就代表谁
super是父类空间的一个标识,你可以理解为父类的一个对象,既然super 是父类空间的一个标识,那么就可以通过super去访问父类的数据.

this和super的使用

a:调用成员变量
this.成员变量 —— 调用本类的成员变量
super.成员变量 ——调用父类的成员变量
b:调用构造方法
this(…) ——调用本类的构造方法
super(…) ——调用父类的构造方法
c:调用成员方法
this.成员方法 ——调用本类的成员方法
super.成员方法 ——调用父类的成员方法

public class Test {
    public static void main(String[] args) {
        Son son = new Son();
        son.show(20);
    }
}

class Father {
    int age = 100;
}

class Son extends Father {
    int age = 50;

    public void show(int age) {
        System.out.println(age);   //20
        System.out.println(this.age);   //50
        System.out.println(super.age);   //100
    }
}

子类中所有的构造方法默认都会访问父类中空参数的构造方法
因为子类会继承父类中的数据,可能还会使用父类的数据。
所以,子类初始化之前,一定要先完成父类数据的初始化。
其实,每一个构造方法的第一条语句默认都是:super()

类 Object 是类层次结构的根类。每个类都使用 Object 作为超类,
Object类 是我们所有类的顶层父类,所有类都是直接或简介继承自他。

class Fu{
			public int num = 10;
			public Fu(){
				System.out.println("fu");
			}
		}
		class Zi extends Fu{
			public int num = 20;
			public Zi(){
				System.out.println("zi");
			}
			public void show(){
				int num = 30;
				System.out.println(num);  //30
				System.out.println(this.num);  //20
				System.out.println(super.num);  //10
			}
		}
		class Test {
			public static void main(String[] args) {
				Zi z = new Zi();
				z.show();
			}
		}

输出:
fu
zi
30
20
10


class Fu {
    static {
        System.out.println("静态代码块Fu");
    }

    {
        System.out.println("构造代码块Fu");
    }

    public Fu() {
        System.out.println("构造方法Fu");
    }
}

class Zi extends Fu {
    static {
        System.out.println("静态代码块Zi");
    }

    {
        System.out.println("构造代码块Zi");
    }

    public Zi() {
        System.out.println("构造方法Zi");
    }
}


class Test {
    public static void main(String[] args) {

        Zi z = new Zi();
    }
}

输出:
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi

继承中成员方法关系

通过子类调用方法时,先查找子类中有没有该方法,如果有就使用;子类中没有再看父类中有没有该方法,有就使用。

方法重写

子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写。

当父类中的方法不能满足子类的需要时,子类就可以重写父类中的方法,这样既保留了父类中的功能,又有了新的功能。

Override和Overload的区别?

Override:方法重写
Overload:方法重载

重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。

重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。

方法重写注意事项

1、父类中的私有方法不能被重写,因为父类私有方法子类根本无法继承。
2、子类重写父类方法时,访问权限不能更低。
3、父类静态方法,子类也必须通过静态方法重写(实际上这算不上方法重写)

final关键字

final修饰特点

修饰类:被修饰的类不能被继承
修饰方法:被修饰的方法不能被重写
修饰变量:被修饰的变量不能被重新赋值,这位这个量其实是个常量

基本类型,是值不能被改变
引用类型,是地址值不能被改变

你可能感兴趣的:(JavaSE)