目录
- 代码块
- 继承
- 方法重写
- final关键字
代码块
代码块:在Java中,使用{}括起来的代码被称为代码块。
分类:根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块
应用:
- 局部代码块 : 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
- 构造代码块:在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
- 静态代码块 :在类中方法外出现,加了static修饰
在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。
演示
class Student {
static {
System.out.println("Student 静态代码块");
}
{
System.out.println("Student 构造代码块");
}
public Student() {
System.out.println("Student 构造方法");
}
}
代码块执行顺序
class StudentDemo {
static {
System.out.println("StudentDemo的静态代码块"); //1
}
public static void main(String[] args) {
System.out.println("我是main方法"); // 2
Student s1 = new Student();
Student s2 = new Student();
}
}class Student {
static {
System.out.println("Student 静态代码块"); //3
}
{
System.out.println("Student 构造代码块"); //4 6
}
public Student() {
System.out.println("Student 构造方法"); //5 //7
}
}
继承
继承:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
格式:
- 通过extends关键字可以实现类与类的继承
- class 子类名 extends 父类名 {}
- 单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类
继承的好处
- 提高了代码的复用性
- 提高了代码的维护性
- 让类与类之间产生了关系,是多态的前提
继承的坏处 - 类的耦合性增强了
- 开发的原则:高内聚,低耦合。
- 耦合:类与类的关系
- 内聚:就是自己完成某件事情的能力
ps:要继承之前先想清楚,不要为了继承而继承
演示
public class MyTest2 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "汤姆";
cat.age = 2;
System.out.println(cat.name);
System.out.println(cat.age);
cat.eat();
cat.sleep();
cat.catcheMouse();
System.out.println("------------------");
Dog dog = new Dog();
dog.name = "旺财";
dog.age = 4;
System.out.println(dog.name);
System.out.println(dog.age);
dog.eat();
dog.sleep();
dog.lookDoor();
}
}
class Animal {
String name;
int age;
public void eat() {
System.out.println("吃饭饭");
}
public void sleep() {
System.out.println("睡觉觉");
}
}
class Cat extends Animal {
public void catcheMouse() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void lookDoor() {
System.out.println("看门");
}
}
继承特点
- Java只支持单继承,不支持多继承。
- Java支持多层继承(继承体系)
演示
public class MyTest {
public static void main(String[] args) {
C c = new C();
int num = c.num;
int b = c.b;
c.aa();
}
}
class A{
int num=100;
private int a=10;
public void aa() {
}
private void show() {
}
}
class B extends A{
int b=1000;
}
class C extends B{
int c=2;
}
继承的注意事项
- Java中继承只支持单继承 一个类只能有一个父类 但是支持多层继承
- 子类不能继承父类私有的成员
- 构造方法不参与继承,父类构造方法,用于子类初始化父类的成员
- 不要为了继承而继承
- 继承体现的是一种 is a 关系
- 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
继承中的变量关系
- 在子类中访问一个变量的查找顺序(“就近原则”)
- 在子类的方法的局部范围找,有就使用
- 在子类的成员范围找,有就使用
- 在父类的成员范围找,有就使用
- 如果还找不到,就报错
super关键字
- 子类局部范围访问父类成员变量
- super代表的是父类存储空间的标识(可以理解成父类的引用,可以操作父类的成员)
演示
public class MyTest {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show(1);
}
}
class Fu{
int num=1000;
int b=1;
}
class Zi extends Fu{
int num=10;
int c=20;
public void show(int num){
System.out.println(num); //1
System.out.println(this.num); //10
System.out.println(super.num); //1000
System.out.println("--------------------");
System.out.println(this.c);
System.out.println(super.b);
}
}
继承中构造方法的关系
-
子类中所有的构造方法默认都会访问父类中空参数的构造方法
-
因为子类会继承父类中的数据,可能还会使用父类的数据。
-
子类初始化之前,一定要先完成父类数据的初始化。
继承中构造方法注意事项演示
public class MyTest {
public static void main(String[] args) {
//new Father();
//当我们在创建子类对象时,会先初始化父类,为什么?
//因为我们子类要去继承父类的一些数据,甚至还要去使用它,那如果父类没有先于子类完成对象父类数据的初始化,子类怎么去继承使用,所以说,我们在创建子类对象时,先要完成父类数据的初始化,所以说先要调用父类的构造,完成父类数据的初始化
//起始在每个类的构造方法中的第一行,有一条默认语句在调用父类的空参构造 super();
Son son = new Son();
}
}
class Father{
int num=100;
public Father() {
super();//调用父类的空参构造
System.out.println("父类的空参构造");
}
}
class Son extends Father{
public Son() {
super();//调用父类的空参构造
System.out.println("子类的空参构造");
}
}
演示2
public class Test2 {
public static void main(String[] args) {
//当我们创建子类对象时,父类字节码文件,先加载进内存
Zi zi = new Zi();
}
}
class Fu {
static {
System.out.println("静态代码块Fu"); //2
}
{
System.out.println("构造代码块Fu");//
}
public Fu() {
System.out.println("构造方法Fu"); //
}
}
class Zi extends Fu {
static {
System.out.println("静态代码块Zi"); //1
}
{
System.out.println("构造代码块Zi"); //
}
public Zi() {
System.out.println("构造方法Zi"); //
}
//运行结果
//*静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi*//
继承中成员方法关系
- 先查找子类中有没有该方法,如果有就使用
- 在看父类中有没有该方法,有就使用
- 如果没有就报错
方法重写
方法重写:子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写。
应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
这样,即沿袭了父类的功能,又定义了子类特有的内容。
注意事项
- 父类中私有方法不能被重写因为父类私有方法子类根本就无法继承
- 子类重写父类方法时,访问权限不能更低
- 父类静态方法,子类也必须通过静态方法进行重写
- 子类重写父类方法的时候,最好声明一模一样。
演示
public class MyTest {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
Cat cat = new Cat();
cat.eat();
}
}
class Animal{
public void eat(){
System.out.println("eat");
}
}
class Dog extends Animal{
public void lookDoor(){
System.out.println("看门");
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
class Cat extends Animal{
public void catchMouse (){
System.out.println("抓老鼠");
}
}
@Override 注解 可以检测这个方法是不是重写父类的方法
ctrl+O 重写父类方法
final关键字
final:由于继承中有一个方法重写的现象,而有时候我们不想让子类去重写父类的方法.这对这种情况java就给我们提供了一个关键字: final ,final关键字是最终的意思,可以修饰类,变量,成员方法。
特点
- 修饰类: 被修饰类不能被继承
- 修饰方法: 被修饰的方法不能被重写
- 修饰变量: 被修饰的变量不能被重新赋值,因为这个量其实是一个常量
修饰局部变量
-
基本类型,是值不能被改变
-
引用类型,是地址值不能被改变
演示
public class MyTest {
public static final int A=100; //公共的静态常量
public static void main(String[] args) {
//final 最终的,可以修饰变量,成员方法,类
//final 修饰变量,这个变量称为常量
//final 修饰方法,子类不能重写,只能继承
//final 修饰类 此类不能被继承
final int NUM=100; //自定义常量 ,常量的命名规范 字母全部大写
//NUM=200;
System.out.println(NUM);
int a = MyTest.A;
new Zi().show();
// private this static final super
}
}
class Fu{
public final void show(){
System.out.println("父类的final方法");
}
public void show1() {
}
public void show2() {
}
public final void show3() {
}
}
class Zi extends Fu{
//@Override
//public void show() {
//
//}
}