Java继承与多态:深入理解继承、组合和多态的精髓!

Java继承与多态:深入理解继承、组合和多态的精髓!

引言

欢迎来到这篇关于Java继承与多态的博客!在Java编程中,继承与多态是两个非常重要的概念,它们为我们构建灵活而高效的代码提供了强大的支持。本文将深入探讨Java继承与多态的原理、语法和实践,帮助读者更好地理解和应用这两个概念。

1. 继承

概念

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

语法

在Java中,使用extends关键字可以创建一个类的子类(派生类),子类会继承父类(基类)的成员变量和方法。

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

class Dog extends Animal{
void bark(){
System.out.println(name + "汪汪汪~~~");
	}
}

public class TestExtend {
public static void main(String[] args) {
Dog dog = new Dog();
// dog类中并没有定义任何成员变量,name和age属性肯定是从父类Animal中继承下来的
System.out.println(dog.name);
System.out.println(dog.age);

// dog访问的eat()和sleep()方法也是从Animal中继承下来的
dog.eat();
dog.sleep();
dog.bark();
}
}
public class Base {
int a;
int b;
}
public class Derived extends Base{
int c;
public void method(){
a = 10; // 访问从父类中继承下来的a
b = 20; // 访问从父类中继承下来的b
c = 30; // 访问子类自己的c
	}
}

父类成员访问

子类可以访问父类的公有成员变量和方法,但不能访问父类的私有成员变量和方法。

class ParentClass {
    public int publicVar;
    private int privateVar;
    
    public void publicMethod() {
        System.out.println("Public method");
    }
    
    private void privateMethod() {
        System.out.println("Private method");
    }
}

class ChildClass extends ParentClass {
    void accessParentMembers() {
        publicVar = 10; // 可以访问父类的公有成员变量
        publicMethod(); // 可以调用父类的公有方法
        // privateVar = 20; // 无法访问父类的私有成员变量
        // privateMethod(); // 无法调用父类的私有方法
    }
}



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

在这里插入图片描述
总结:

  1. 通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到
    则访问,否则编译报错。
  2. 通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法适传递的参数选择合适的方法访问,如果没有则报错;

super关键字

在子类方法中,如果想要明确访问父类中成员时,借助super关键字即可。该关键字主要作用:在子类方法中访问父类的成员。

class Base {
    public int a = 1;
    public int b = 2;
}

class Derived extends Base {
    public int a = 100;
    public int c = 3;
    public void test() {
        System.out.println(super.a);
        System.out.println(this.a);
        System.out.println(this.b);
        System.out.println(super.b);
        System.out.println(this.c);
    }
}

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

在这里插入图片描述

子类构造方法

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

public class Base {
public Base(){
System.out.println("Base()");
}
}
public class Derived extends Base{
public Derived(){
// super(); // 注意子类构造方法中默认会调用基类的无参构造方法:super(),
// 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,
// 并且只能出现一次
System.out.println("Derived()");
}
}
public class Test {
public static void main(String[] args) {
Derived d = new Derived();
}
}

结果打印:
Base()
Derived()

super和this

super:可以当作一个关键字,可以访问父类继承内容。
this:代表父类对象引用。

再谈初始化

class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Person:构造方法执行");
}
{
System.out.println("Person:实例代码块执行");
}
static {
System.out.println("Person:静态代码块执行");
}
}
class Student extends Person{
public Student(String name,int age) {
super(name,age);
System.out.println("Student:构造方法执行");
}
{
System.out.println("Student:实例代码块执行");
}
static {
System.out.println("Student:静态代码块执行");
}
}
public class TestDemo4 {
public static void main(String[] args) {
Student student1 = new Student("张三",19);
System.out.println("===========================");
Student student2 = new Student("gaobo",20);
}
public static void main1(String[] args) {
Person person1 = new Person("bit",10);
System.out.println("============================");
Person person2 = new Person("gaobo",20);
}
}

在这里插入图片描述
结论:

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

protected 关键字

//Test.java

public class Test {
    public int a;
    protected int c = 99;


    public void func() {
        System.out.println(c);
    }
}

//TestProtected.java
public class TestProtected {
    public static void main(String[] args) {
        Test test = new Test();
        System.out.println(test.c);
    }
}

//TestDemo.java
public class TestDemo extends Test{

    public void test() {
        System.out.println(super.c);
    }

    public static void main(String[] args) {
        Test test = new Test();
        ///System.out.println(test.c);
        //System.out.println(super.c);
    }
}

结论:在不同包的子类中,可以用super进行调用
在这里插入图片描述

final 关键字

final关键可以用来修饰变量、成员方法以及类。

  1. 修饰变量或字段,表示常量(即不能修改)
final int a = 10;
a = 20; // 编译出错
  1. 修饰类:表示此类不能被继承
final public class Animal {
...
}
public class Bird extends Animal {
...
}
// 编译出错
Error:(3, 27) java: 无法从最终com.bit.Animal进行继承
  1. 修饰方法:表示该方法不能被重写(后序介绍)

2. 多态

概念

通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。

多态实现条件

在java中要实现多态,必须要满足如下几个条件,缺一不可:

  1. 必须在继承体系下
  2. 子类必须要对父类中方法进行重写
  3. 通过父类的引用调用重写的方法

多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法。

class Animal {
    void sound() {
        System.out.println("Animal makes sound");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    void sound() {
        System.out.println("Cat meows");
    }
}

class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
        
        dog.sound(); // 输出:Dog barks
        cat.sound(); // 输出:Cat meows
    }
}

重写(override)

规则:

  1. 方法名相同
  2. 方法的参数列表相同(个数,顺序,类型)
  3. 方法的返回值相同
class ParentClass {
    void show() {
        System.out.println("Parent class method");
    }
}

class ChildClass extends ParentClass {
    void show() {
        System.out.println("Child class method");
    }
}

class Main {
    public static void main(String[] args) {
        ParentClass obj = new ChildClass();
        obj.show(); // 输出:Child class method
    }
}

总结:

  1. 静态方法不能被重写
  2. 被private修饰的方法不能被重写
  3. 被final修饰的方法不能被重写
  4. 如果方法被重写,那么子类权限>=父类权限
    private<包访问权限<protected<public

动态绑定

class B {
    public B() {
        func();
    }

    public void func() {
        System.out.println("B::FUNC()!");
    }
}
class D extends B {
    private int num = 1;
    public void func() {
        System.out.println("D::FUNC()!" + num);
    }
}
public class Test3 {
    public static void main(String[] args) {
        D d = new D();
    }
}

在这里插入图片描述
在这里插入图片描述

向上转型

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。
语法格式:父类类型 对象名 = new 子类类型()

Animal animal = new Cat("元宝",2)

animal是父类类型,但可以引用一个子类对象,因为是从小范围向大范围的转换。

【使用场景】

  1. 直接赋值
  2. 方法传参
  3. 方法返回
public class TestAnimal {
// 2. 方法传参:形参为父类型引用,可以接收任意子类的对象
public static void eatFood(Animal a){
a.eat();
}
// 3. 作返回值:返回任意子类对象
public static Animal buyAnimal(String var){
if("狗".equals(var) ){
return new Dog("狗狗",1);
}else if("猫" .equals(var)){
return new Cat("猫猫", 1);
}else{
return null;
}
}
public static void main(String[] args) {
Animal cat = new Cat("元宝",2); // 1. 直接赋值:子类对象赋值给父类对象
Dog dog = new Dog("小七", 1);
eatFood(cat);
eatFood(dog);
Animal animal = buyAnimal("狗");
animal.eat();
animal = buyAnimal("猫");
animal.eat();
}
}

总结:

向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调用到子类特有的方法。

结尾

通过本文的学习,相信你对Java继承与多态有了更深入的理解和掌握。继承与多态是Java编程中非常重要的概念,可以帮助我们编写更加灵活、可扩展和易维护的代码。希望本文能够帮助你更好地应用继承与多态,提升自己的编程水平。如果有任何疑问或想法,欢迎在评论区分享,让我们一起学习进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/433325.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年冲刺年薪40w,Android岗面试

一个程序员&#xff0c;如果不想35 岁被淘汰&#xff0c;请把它当成一种信仰&#xff01; 25岁&#xff0c;一个北漂程序员&#xff0c;入职三年&#xff0c;Android中级工程师&#xff0c;月薪15k&#xff0c;965的工作经常干成996&#xff0c;比起老家的同龄人&#xff0c;我…

校招中的“熟悉linux操作系统”一般是指达到什么程度?

校招中的“熟悉linux操作系统”一般是指达到什么程度&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Linux的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&am…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:PanGesture)

拖动手势事件&#xff0c;当滑动的最小距离超过设定的最小值时触发拖动手势事件。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 接口 PanGesture(value?: { fingers?: number; direction?: PanDir…

three.js如何实现简易3D机房?(二)模型加载的过渡动画

接上一篇&#xff1a; three.js如何实现简易3D机房&#xff1f;&#xff08;一&#xff09;基础准备-下&#xff1a;http://t.csdnimg.cn/TTI1P 目录 六、自定义过渡动画 1.过渡动画组件 2.模型加载时使用 根据模型大小&#xff0c;可以自定义模型加载的过渡动画效果&am…

修改表中某个字段等于另一个字段减去 2 小时的 SQL

需求&#xff1a;将表中到达时间按照客户要求改为比赛时间的提前 N 小时&#xff0c;具体如下&#xff1a; 表结构 update contestSchedule SET mainRefereeArrivalTimeDATE_FORMAT(CONCAT(2024-03-04 ,gameTime)- INTERVAL 2 HOUR, %H:%i), assistantRefereeArrivalTimeDAT…

算法沉淀——贪心算法一(leetcode真题剖析)

算法沉淀——贪心算法一 01.柠檬水找零02.将数组和减半的最少操作次数03.最大数04.摆动序列 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种基于贪心策略的优化算法&#xff0c;它通常用于求解最优化问题&#xff0c;每一步都选择当前状态下的最优解&#xff0c;以期…

动动嘴就能搞研发?百度Comate带你0门槛玩转代码

3月1日&#xff0c;百度旗下智能代码助手Baidu Comate 又添两大重磅能力&#xff1a;“Comate ” 开放平台、AutoWork “私人研发助理”&#xff0c;为行业首家免费开放试用。本次发布&#xff0c;Baidu Comate 将更加贴合软件研发现场&#xff0c;通过易用的研发平台、丰富的插…

Docker的安装跟基础使用一篇文章包会

目录 国内源安装新版本 1、清理环境 2、配置docker yum源 3、安装启动 4、启动Docker服务 5、修改docker数据存放位置 6、配置加速器 现在我们已经完成了docker的安装和初始配置。以下为基本测试使用 自带源安装的版本太低 docker官方源安装的话速度太慢了 所以本篇文…

2023年算法OOA-DBSCAN聚类

2023年算法OOA-DBSCAN聚类 鱼鹰优化算法&#xff08;Osprey optimization algorithm&#xff0c;OOA&#xff09;由Mohammad Dehghani 和 Pavel Trojovsk于2023年提出&#xff0c;其模拟鱼鹰的捕食行为。鱼鹰是鹰形目、鹗科、鹗属的仅有的一种中型猛禽。 DBSCAN聚类算法&#x…

RLNNA-DBSCAN聚类

RLNNA-DBSCAN聚类 RLNNA算法&#xff08;基于强化学习的神经网络优化算法&#xff09;是一种性能较佳的优化算法。DBSCAN聚类算法&#xff08;密度聚类算法&#xff09;是一种基于密度的聚类算法&#xff0c;其主要思想是通过寻找样本点周围的密度可达关系来聚类数据。 使用RL…

小白跟做江科大51单片机之DS1302可调时钟

原理部分 1.DS1302可调时钟介绍 单片机定时器主要占用CPU时间&#xff0c;掉电不能继续运行 图1 2.原理 图2 内部有寄存器&#xff0c;寄存的时候以时分秒寄存&#xff0c;以通信协议实现数据交互&#xff0c;就可以实现对数据进行访问和读写 3.主要寄存器定义 CE芯片使能…

线性代数 --- 特征值与特征向量

特征值与特征向量 已知任意向量x&#xff0c;现有矩阵A对x进行操作后&#xff0c;得到新的向量Ax。这就好比是自变量x与函数f(x)的关系一样&#xff0c;向量x通过类似“函数”的处理得到了一个新的向量Ax。这个新的向量可能和原向量x方向相同&#xff0c;也可能不同(事实上大多…

五、布局布线约束、系统优化参数、时序优化收敛 关键技术点

在实际的工程当中&#xff0c;出现了时序违例的情况如何解决呢&#xff1f; 本章内容将介绍例外约束、布局布线的具体操作&#xff0c;实现系统参数的优化。 **前言:**通过约束时钟&#xff0c;比如基准时钟&#xff0c;和生成时钟&#xff0c;让我们的综合工具知道我们的时序…

2024年阿里Android高级面试题分享,送给正在迷茫的你

前言 很多公司在招人这件事情上都会面临一个问题&#xff1b; “我们的招聘要求又不高&#xff0c;能做项目就行&#xff0c;但为什么就是招不到人&#xff1f;” 很多公司还面临一个问题&#xff0c;招聘的时候这人各方面都不错&#xff0c;但上岗了就是不出活&#xff0c;绩…

2024春招面试,文末有彩蛋

前言 Flutter 作为Google出品的一个新兴的跨平台移动客户端UI开发框架&#xff0c;正在被越来越多的开发者和组织使用&#xff0c;包括阿里的咸鱼、腾讯的微信等。 今天&#xff0c;我主要讲解Flutter中文本组件方面的Widget&#xff0c;包括Text、RichText、TextField&#…

元宇宙线上展厅——如何利用3D展示平台创新吸引客户与展示产品

在数字化转型的浪潮中&#xff0c;元宇宙线上展厅作为一种全新的虚拟展示平台&#xff0c;正以其独特的创新功能和沉浸式体验&#xff0c;吸引着越来越多的企业和用户的目光。 一、元宇宙线上展厅的创新功能 1、沉浸式体验与交互设计 元宇宙线上展厅通过先进的3D建模技术和VR技…

selenium4的相对定位

selenium4相对定位 Selenium 4新增了相对定位器&#xff0c;能帮助用户查找元素附近的其他元素。可用的相对定位器有above、below、toLeftOf、toRightOf、near。在Selenium 4中&#xff0c;find_element方法能够接受一个新方法withTagName&#xff0c;它将返回一个RelativeLoca…

《2023年DDoS攻击现状及趋势报告》

执行概要 与第一季度相比&#xff0c;2023年第二季度的DDoS攻击活动增长了387%。 电信公司遭受的攻击最为频繁&#xff0c;占总攻击量的50%&#xff0c;在2023年上半年发生了超过37,000次攻击&#xff1b;然而&#xff0c;在所有行业中&#xff0c;电信公司的攻击活动在同一时…

mac电脑总卡蓝屏是怎么回事,苹果电脑老卡蓝屏怎么办

电脑老卡蓝屏是比较常见的电脑故障之一&#xff0c;导致这一问题的出现很可能是电脑本身的硬件&#xff0c;或电脑上的驱动安装错误&#xff0c;没法运行&#xff0c;当然也不排除其他的一些因素。虽说电脑蓝屏是电脑几乎都会出现的小毛病&#xff0c;不足以致命&#xff0c;但…

Day19:信息打点-红蓝队自动化项目资产侦察武器库部署企查产权网络空间

目录 各类红蓝队优秀工具项目集合 自动化-武器库部署-F8x 自动化-网络空间-AsamF 自动化-企查信息-ENScan 自动化-综合架构-ARL&Nemo 思维导图 章节知识点 Web&#xff1a;语言/CMS/中间件/数据库/系统/WAF等 系统&#xff1a;操作系统/端口服务/网络环境/防火墙等 应…