java 继承

一.代码块
概念:
使用{} 括起来的代码,称为代码块

分类:
根据它位置和声明的不同,我们可以将代码块分为局部代码块,构造代码块,静态代码块,同步代码块(多线程涉及)

a. 局部代码块
限定了变量的生命周期,变量在局部代码块中定义的,那么出来局部代码块之后,就访问不到了。在局部代码块中定义的变量,
在出了代码块之后,内存就会释放掉。

作用: 主要就是节约内存.

局部代码块中定义的变量,虽然说作用域是局部的,但是如果存在外部嵌套的代码块,且在局部代码块定义之前就定义了某个变量,
那么在我们局部的代码块中就不可以定义相同名称的变量。
但是如果在局部代码块执行之后,去定义一个和局部代码块中相同名称的变量,是可以的。因为局部代码块中的变量已经失去了作用域范围。

b.构造代码块
概念:
类中方法外出现,每次调用构造方法的时候,都会优先先调用构造代码块。

特点:
没创建一个对象,都会调用一次我们的构造代码块.

作用:
如果存在很多重载的构造方法,而且每个里面需要执行 相同的逻辑,那么就可以考虑将这些代码提取到构造代码块中来执行。
让我们代码结构更简练。增强了维护性.
使用场景其实不太多见。

c.静态代码块
概念:
类中方法外出现,但是用static 来进行修饰。

特点:
随着类加载的时候执行。

用处:
适用于整个软件的生命周期中,只需要执行一次的业务逻辑代码。
比如我们之后数据库的操作.

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

    public static void main(String[] args){

        Person person = new Person();
        System.out.println("--------------------");
        Person person1 = new Person(20);
    }

}

class Person{

    int age;

    int[] num;

    static{
        System.out.println("调用了静态代码块");
    }

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

    //默认的构造方法
    Person(){
        System.out.println("默认构造");

        // 数组成员变量我们依次赋值
    }

    Person(int age){
        this.age = age;
        System.out.println("非默认构造");

        // 数组成员变量我们依次赋值
    }

}

打印结果
这里写图片描述

二.继承
特点
1. 子类继承父类,继承父类的成员变量和成员方法。但是他们各自拥有的各自的成员变量,所以他们的值,并不会继承。
2. 对于父类中的私有成员变量和私有方法,子类是无法继承的。

继承优点:
a.提高了代码的复用性
b.提高了代码的维护性

继承缺点:
a.类的耦合性增强了。
开发的原则:
高内聚,低耦合.

耦合: 类和类之间的关系
内聚: 自己独立完成某件事情的能力.

电视类: 品牌, 价格 , 尺寸
手机类: 品牌, 价格 , 尺寸, 操作系统

上层抽出来一个类: 电器类(品牌,价格,尺寸)

3.只支持单继承,但是可以支持多层继承
继承是相互叠加的,子类继承的时候,会递归似的寻找父类中是否还存在继承,会继承整个层级直到最根部类的属性和方法。

4.对于构造方法是无法继承的。
但是有办法可以调用父类的构造方法。

继承关系中访问成员变量:

a.不同名的成员变量
子类可以直接访问和使用父类继承的非私有的成员变量

b.同名的成员变量
优先原则: 如果子类中定义了和父类中相同名字的成员变量,会优先访问子类的该变量
如果想要依然访问到父类中的同名变量,我们需要加上super关键字来获取.

this: 当前对象的引用
super: 父类对象的引用

this: 可以访问到子类中的变量,也可以访问到父类中的变量
super: 访问父类中的变量

继承关系中访问成员方法:
a.不同名的方法
子类可以直接调用到父类的方法

b.同名的方法
当父类和子类出现同名方法的时候(同名方法: 指的返回值类型(父子类关系是可以的),方法名称以及方法接收的形参列表要一模一样)

在这种情况下:
当我们子类调用该方法时,会有优先原则的处理,就是会调用子类的该方法。
public class ExtendsDemo1{

public static void main(String[] args){  
    Father father = new Father();  
    father.setName("小诸葛");//外部方法赋值  
    Son son = new Son();  
    /* 
     * 子类和父类各自拥有的各自的成员变量,所以他们的值并不会继承 
     * 可以这样理解:父类创建一个对象后给对象属性赋值 
     * 此时子类继承父类,但是此时子类继承的是父类的原始属性和方法 
     * (可以理解为未创建对象之前的属性和方法) 
     * 

//主要目的:子类和父类各自拥有的各自的成员变量,所以他们的值并不会继承

public class ExtendsDemo1{  

    public static void main(String[] args){  
        Father father = new Father();  
        father.setName("小诸葛");//外部方法赋值  
        Son son = new Son();  
        /* 
         * 子类和父类各自拥有的各自的成员变量,所以他们的值并不会继承 
         * 可以这样理解:父类创建一个对象后给对象属性赋值 
         * 此时子类继承父类,但是此时子类继承的是父类的原始属性和方法 
         * (可以理解为未创建对象之前的属性和方法) 
         */  
        son.speak();  
    }  
}  

class Father{  
    //JavaBean类  
    private  int age;  
    private  String name;  
    /* 
     * 若在此直接赋值,则子类也继承此值 
     * 即:private  String name="小花"; 
     * 若修改成private static String name; 
     * 调用外部方法对父类赋值后子类仍然能继承此值 
     */  
    void setAge(int age){  
        this.age = age;  
    }  

    void setName(String name){  
        this.name = name;  
    }  

    int getAge(){  
        return age;  
    }  

    String getName(){  
        return name;  
    }  

    void speak(){  
        System.out.println("爸爸大声喊出我的名字:"+name);  
    }  
}  

class Son extends Father{  

}  

补充:
1.

方法的重写(覆盖):
存在于继承关系中,子类中定义的方法和父类中的方法完全一样的时候(返回值类型父子类关系是可以的),我们在通过子类对象来访问该方法的时候,就会调用到子类的方法

注意事项:
子类不能重写父类的私有方法
子类重写父类方法的时候,提供的访问权限不能更低
子类覆盖父类方法,如果父类是静态方法的话,子类也必须是静态方法才可以成功覆盖,也就是重写

方法重载:
同一个类中,如果我们有多个相同方法名的方法,但是他们的形参列表是不同的,那么这种方式我们就称为方法的重载
在调用的时候,jvm能够通过方法签名来区分到我们到底调用的是哪个方法

关于方法重写和方法重载的返回值约束:
方法重载:与返回值类型无关,必须参数列表不同
方法重写:子类与父类返回值类型(父子类关系是可以的) 必须相同

this:可以访问子类的方法,也可以访问父类的方法
super:只能够访问父类的方法

2.

我们一个文件在编译之后产生的.class 文件的数量,取决于在该文件中定义的class的数量(非内部类),而且是不引入其他类的情况下

继承中构造方法的调用:
特点:
1 创建子类对象的时候,一定会优先去创建父类的对象;因为要创建父类对象,所以就需要去调用到父类的构造方法
2 对于我们所有的类的构造方法的第一行,第一行在我们没有自己添加this(…)或者super(…)的情况下都会去帮我们默认的添加super()

如果父类中不存在默认的构造,子类依然要创建对象,那么子类就需要显示的指明调用个父类哪个构造方法,才能保证父类对象创建的成功。

明确一点:
a 一定要保证父类对象的创建成功
b 构造方法的第一行,如果我们添加了自己调用的this(…),或者super(…),系统就不会为我们默认的添加super()
c 我们的this(…)或者super(…) 必须放到第一行,否则编译错误,且二者只能有其一
对c说明:this(…)调用的是子类的另一个构造方法,在此构造方法中调用父类super(参数),所以二者只需其一
通俗理解:子类要想创建对象,首先要创建父类对象,所以就需要调用父类的构造方法;当程序执行到new去创建子类对象的时候,首先会去调用子类的构造方法,若子类构造方法中没有his(…)或者super(…) ,jvm会默认添加super()调用父类的构造方法,进而完成父类对象的创建,然后再完成子类构造方法,进而创建子类对象.

/* 
在创建子类对象的时候,会先调用到父类的构造方法,再去创建父类的对象 
构造方法调用构造方法 
this(参数)---调用同类 
super(参数)--调用父类 
*/  

public class ExtendsDemo5 {  

    public static void main(String[] args) {  
        Son son = new Son();  
    }  
}  

class Father {  

    Father() {  
        System.out.println("调用father 默认构造");  
        System.out.println("father对象创建完毕");  
    }  

    Father(int num) {  
        System.out.println("调用father 有参构造");  
        System.out.println("father对象创建完毕");  
    }  
}  

class Son extends Father {  

    Son() {  
        this(10);// 不要此行的编译结果  
        // this(10)调用同类的构造方法,此时就不会帮我们再去默认添加super(),  
        System.out.println("son 默认构造");  
    }  

    Son(int num) {  
        super(10);// 可以删除此行看看编译结果  
        // 第一行没有this或者super,就会帮我们默认添加super()  
        System.out.println("son 有参构造");  
        System.out.println("-------------");  
    }  

}  

三.final关键字
a final修饰类
final如果修饰一个类,该类不能被继承

b final修饰类的成员变量
该成员变量的值不可修改
问题: 那么什么时候初始化这个值?
答:在对象创建之前都可以
a 构造代码块中可以进行初始化
b 构造方法中可以进行初始化
c 定义成员变量的时候,可以直接进行初始化

注意一点:
1)这三种方式同时只能用一种
2)在大多数的场景下,我们的final成员变量都会配合public static 一起使用

//final修饰的常量类,变量命名都要大写,而且单词之间要用_分割开
形如:
class A{
public static final double PI = 3.14;
public static final double RATE = 2.86;
}

使用方式:类名.变量名
A.PI
A.RATE

final修饰的static变量的初始化时机:
a 在创建静态final成员变量的时候,直接进行初始化
b 在静态代码块中进行初始化

public class FinalDemo1 {  
         //final修饰的static变量初始化的一种方式  
    public static void main(String[] args) {  
        Person person = new Person();  
        person.sayNum();  
    }  

}  

class Person {  

    // final 修饰成员变量,该值不可修改.  
    static final int num;//第二种方式,定义的时候直接赋值  

    static {  
        num = 10;   //第一种方式:通过静态代码块赋值  
    }  

    Person() {  

    }  

    void sayNum() {  
        System.out.println("静态变量初始化:" + num);  
    }  
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值