JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合)

这篇具有很好参考价值的文章主要介绍了JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、继承

继承 (inheritance) 机制 :是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性 的基础上进行扩展,增加新功能 ,这样产生新的类,称 派生类
        继承呈现了面向对象程序设计的层次结构, 体现了 由简单到复杂的认知过程。
        继承主要解决的问题是:共性的抽取,实现代码复用

(1)继承的语法

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

注意:
1. 子类会将父类中的成员变量或者成员方法继承到子类中了
2. 子类继承父类之后,要新添加自己的成员(一般是与其他子类不同的),便于区别。

继承是一种思想。对共性进行提取,减少代码的冗余,达到了代码复用的效果。

例如:JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 (2)父类成员的访问

1.子类中访问父类的 成员变量

1)访问子类、父类成员变量 不同名

不同名直接访问 变量名或者 this.变量名

class Base{
    public int a;
    public int b;
}

//派生类(子类)
class Derived extends Base{
    public int c;
    public void method(){
        //访问从父类继承的a和b
        a = 1;
        b = 2;
        //访问子类自身的c
        c = 3;
    }
}

 JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

2)访问 子类、父类成员变量 同名

同名的情况下:(就近原则:优先子类自己)

当子类有该成员变量,优先访问子类自己的成员变量。

当子类当中不存在该成员变量,则访问父类继承下的。如果父类也没有,则编译报错

//基类(父类)
class Base{
    public int a = 10;
    public int b = 20;
}

//派生类(子类)
class Derived extends Base{
    public int a = 1;
    public void method(){
        //访问从父类继承的a和b
        System.out.println("a = "+a);//1
        System.out.println("b = "+b);//20
    }
}

public class Test2 {
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.method();
    }
}

 如果要访问父类的成员变量,使用 super.变量名

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

2.子类中访问父类的 成员方法

1)访问 子类、父类成员方法 不同名

不同名,优先在子类中找,找到则访问,否则在父类中找,找到 则访问,否则编译报错。

class Base{
    public void method(){
        System.out.println("Base:父类成员方法!");
    }
}
class Derived extends Base{
    public void method2(){
        System.out.println("Derived:子类成员方法!");
    }
    public void test(){
        method();
        method2();
    }
}
public class Test2 {
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.test();
    }

}
JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言
2)访问 子类、父类成员方法 同名
同名,优先访问子类。子类没有,在父类继承的方法中找,父类没有,编译报错
class Base{
    public void method(){
        System.out.println("Base:父类成员方法!");
    }
}
class Derived extends Base{
    public void method(){
        System.out.println("Derived:子类成员方法!");
    }
    public void method2(){
        System.out.println("Derived:子类成员方法!");
    }
    public void test(){
        method();
        method2();
    }
}
public class Test2 {
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.test();
    }

}
JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 如果要访问父类方法,使用super.methodJavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

3.子类构造方法

子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法。

也就是说,子类在构造完成之前,一定要先帮助父类初始化

package demo1;

class Animal{
    public String name;
    public int age;
    public  void eat(){
        System.out.println(this.name+"正在吃饭~~");
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

//    public Animal(){
//
//    }

}
//继承
//extends 拓展,扩展 继承
class Dog extends Animal{

//    public Dog(){
//        super();
//    }
    public Dog(String name, int age){
        //调用父类构造方法
        super(name,age);//帮助初始化 子类从父类继承过来的成员,并不会 生成父类对象
        System.out.println("Dog调用父类构造方法");

        //super("小黑",3);
    }
    public  void bark(){
        System.out.println(this.name+"旺旺叫~~");
    }
}
class Cat extends Animal{

    public  void miaomiao(){
        System.out.println(this.name+"喵喵叫~~");
    }

    public Cat(String name, int age) {
        super(name, age);
        System.out.println("Cat调用父类构造方法");

    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog("小黑",3);
        dog.eat();
        dog.bark();

        System.out.println("==========");

        Cat cat = new Cat("小白",4);
        cat.eat();
        cat.miaomiao();
    }
}
1) 当给父类Animal提供了一个带参数的构造方法时,子类报错了

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

就是因为,在调用子类构造方法时,得先初始化父类变量,这样就不会报错了

 2)不带参数的构造方法时,没有报错。而且之前没写构造方法的时候,也没报错

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 那是因为,没写的时候,默认会生成一个子类调用父类的构造方法

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 注意:同this一样,只能调用1次。而且必须得放在构造语句的第一行

否则会像这样报错

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

要向打印 ,可以放在super语句的后面

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 然后主函数调用写好的继承

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 4.super和this的小总结

共性:
super.成员变量
super.成员方法
super()调用父类构造方法

**针对当前对象的父类

this.成员变量
this.成员方法
this()调用父类构造方法
**针对当前对象
不同:
1. this 是当前对象的引用,当前对象即调用实例方法的对象, super 相当于是子类对象中从父类继承下来部分成员的引用
2. 在非静态成员方法中, this 用来访问本类的方法和属性, super 用来访问父类继承下来的方法和属性
3. 在构造方法中: this(...) 用于调用本类构造方法, super(...) 用于调用父类构造方法,两种调用不能同时在构造 方法中出现
4. 构造方法中一定会存在 super(...) 的调用,用户没有写编译器也会增加,但是 this(...) 用户不写则没有

二、再谈初始化  - 观察代码块执行顺序

package demo1;

class Animal{
    public String name;
    public int age;
    public  void eat(){
        System.out.println(this.name+"正在吃饭~~");
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("父类:构造方法");
    }

//    public Animal(){
//
//    }
    static {
        System.out.println("父类:静态代码块");
    }
    {
        System.out.println("父类:实例化代码块");

    }
}
//继承
//extends 拓展,扩展 继承
class Dog extends Animal{

//    public Dog(){
//        super();
//    }
    public Dog(String name, int age){
        //调用父类构造方法
        super(name,age);//帮助初始化 子类从父类继承过来的成员,并不会 生成父类对象
        System.out.println("子类:构造方法");

        //super("小黑",3);
    }
    public  void bark(){
        System.out.println(this.name+"旺旺叫~~");
    }

    static {
        System.out.println("子类:静态代码块");
    }
    {
        System.out.println("子类:实例化代码块");

    }
}
class Cat extends Animal{

    public  void miaomiao(){
        System.out.println(this.name+"喵喵叫~~");
    }

    public Cat(String name, int age) {
        super(name, age);
        System.out.println("Cat调用父类构造方法");

    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog("小黑",3);
        
    }
    
}

通过分析执行结果,得出以下结论:

1父类静态代码块 优先于 子类静态代码块执行,且是最早执行
2父类实例代码块父类构造方法紧接着执行
3子类的实例代码块子类构造方法紧接着再执行
4第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 当再实例化一个对象时,发现静态代码块没有被执行

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 因为静态代码块只会执行一次 

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

三、protect 关键字

 protected常用在继承中JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

1.protected同一包中同一类可以访问

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 2.protected同一包中不一类可以访问

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 3.protected不同一包的子类可以访问。(这个继承的类必须时public访问权限) 

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 4.注意:不能定义类的时候加Protected、Private

Java中不能这样写,语法不支持

 JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 四、继承方式

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 以动物为例,可以有很多继承,橘猫可以继承中华田园猫,中华田园猫可以继承猫,猫可以继承动物,动物也可以继续继承..

但是越往后继承,代码就会越复杂。 一般我们不希望出现超过三层的继承关系.

  1.继承方式 - Java中不支持多继承。

注意: Java中不支持多继承。之后接口可以解决这个多继承的问题。

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 2.fifinal 关键字

fifinal关键可以用来修饰变量、成员方法以及类。
当继承层次过多,不希望再继承的时候加上final, 代表当前类或者变量等,不能继承了

1)修饰变量 ,该变量就变成常量了,只能被初始化一次

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

只能初始化一次,这两种都可以

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

 2)修饰方法,表示当前该方法不能被继承了

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

所以这里继承的时候报错了

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合),Java,java,开发语言

五、继承与组合

        和继承类似, 组合也是一种表达类之间关系的方式 , 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法 (诸如 extends 这样的关键字 ), 仅仅是将一个类的实例作为另外一个类的字段。
继承表示对象之间是 is-a 的关系 ,比如:狗是动物,猫是动物
        继承抽取共性
组合表示对象之间是 has-a 的关系 ,比如:学校
        组合将所有类合并到一起复用

 组合文章来源地址https://www.toymoban.com/news/detail-632832.html

class Student{

}
class Teacher{

}
class Classroom{

}
class School{
    //组合,可以复用这些属性和方法
    public Classroom classroom;
    public Student[] students;//默认null
    public Teacher[] teachers;
    public int a;
    public School(){
        this.students = new Student[10];
        this.teachers = new Teacher[10];

    }
}

到了这里,关于JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【JavaSE】解密 继承和多态(上)

    本篇将会通过典型代码案例来揭开 Java中继承和多态 的神秘面纱~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 继承 继承代码举例 子类访问父类的成员变量和方法 子类访问父类的成员变量 super this和super比较 相同点 区别 ​编辑 子类访

    2024年04月09日
    浏览(34)
  • Pytorch权重初始化/参数初始化

    refer: 【Pytorch】各网络层的默认初始化方法 https://blog.csdn.net/guofei_fly/article/details/105109883 其实Pytorch初始化方法就在各自的层的 def reset_parameters(self) - None: 方法中。 有人可能会问 为什么这个方法和Pytorch直接出来的权重初始值不一样 ?单步调试会发现其实这个方法运行了至少两

    2024年02月11日
    浏览(62)
  • Linux内存初始化-启动阶段的内存初始化

    本文代码基于ARM64平台, Linux kernel 5.15 在加载kernel 之前, kernel对于系统是有一定要求的,明确规定了boot阶段必须要把MMU关闭: 那么在进入kernel之后, 就必须有一个使能MMU, 建立映射的过程, 本文描述kernel启动阶段进行内存初始化相关的操作。 在初始化阶段,我们mapping二段

    2024年02月08日
    浏览(76)
  • 【温故而知新】JavaScript初始化/初始化加载

    在JavaScript中,对象、数组、函数、类等都可以通过不同的方式进行初始化。以下是几种常见的初始化方式: 对象初始化: 使用字面量方式: 使用构造函数方式: 数组初始化: 使用字面量方式: 使用构造函数方式: 函数初始化: 类初始化: 使用Array的of和from方法进行数组

    2024年01月24日
    浏览(71)
  • 深度学习参数初始化(二)Kaiming初始化 含代码

    目录 一、介绍 二、基础知识 三、Kaiming初始化的假设条件  四、Kaiming初始化的简单的公式推导 1.前向传播 2.反向传播 五、Pytorch实现 深度学习参数初始化系列: (一)Xavier初始化 含代码 (二)Kaiming初始化 含代码         Kaiming初始化论文地址:https://arxiv.org/abs/1502.01

    2024年02月04日
    浏览(74)
  • 【随机种子初始化】一个神经网络模型初始化的大坑

    半年前写了一个模型,取得了不错的效果(简称项目文件1),于是整理了一番代码,保存为了一个新的项目(简称项目文件2)。半年后的今天,我重新训练这个整理过的模型,即项目文件2,没有修改任何的超参数,并且保持完全一致的随机种子,但是始终无法完全复现出半

    2024年02月09日
    浏览(64)
  • 初始化磁盘选哪个格式 初始化磁盘分区形式选什么好

    在 初始化磁盘 之前,我们应该先明确什么时候需要初始化磁盘,通常是在电脑安装了SSD固态硬盘,计算机无法正常读取该固态硬盘时。或者需要腾空移动磁盘,以做它用时。那么初始化磁盘时,有哪些格式呢?如今主流的是NTFS格式。也有FAT 32格式,但读写性能会比较差。

    2024年02月09日
    浏览(44)
  • c# 初始化列表,并给列表里面所有的元素进行初始化

    Enumerable.Repeat 方法是用于生成一个包含指定元素重复若干次的序列。它接受两个参数,第一个参数是要重复的元素,第二个参数是重复次数。 下面是 Enumerable.Repeat 方法的用法和示例:

    2024年02月13日
    浏览(45)
  • 官答|初始化GreatSQL报错无法找到数据目录或初始化数据字典失败

    GreatSQL推出新栏目——官答 官答栏目针对GreatSQL数据库中的问题,选取官方论坛和讨论群中的典型提问进行深入解答。内容涵盖数据库安装部署、配置优化、故障排查、性能测试等方面。 在文章中,我们不仅提供解决方案,还会结合实例深入剖析问题的成因,提升读者对GreatSQL数据

    2024年02月04日
    浏览(61)
  • media设备节点初始化与Video4Linux初始化

    media_devnode_init函数是一个内核初始化函数,用于在Linux内核启动期间进行设备节点初始化。 函数的主要作用是创建媒体设备节点(device node)并将其注册到系统的设备树中。媒体设备节点用于表示媒体设备(如摄像头、音频设备等),它们在/dev目录下以特定的名称存在,并允

    2024年02月05日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包