Java继承和多态

文章目录

  • 继承
        • 成员继承
        • 构造方法
          • super和this的区别
          • 代码块构造顺序
        • 限定修饰符
        • final
        • 继承和组合
  • 多态
        • 向上转型
        • 重写
          • 动态绑定
          • 重写注意事项
        • 向下转型
        • 多态优点
        • 注意

继承

成员继承
class Animal{public String name;public int age;public int a=10;public void doSomething(){System.out.println("Animal do something!");}public void eat(){System.out.println("Animal eat!");}
}
//java中只能是单继承,也就是说只能继承一个类
class Dog extends Animal{//继承关键字int a=20;public void func(){System.out.println("a:"+a);//当子类和父类的成员变量冲突时,优先访问自己的System.out.println("base a:"+super.a);//就是想访问基类的,用Super//super只是一个关键字,并不是父类的引用,因为并没有实例化对象//只是提供一种功能,就是在子类中访问父类的成员变量/方法//只能指代父类,不能指代爷爷类}//this 和super都是和对象相关的,所以无法在静态方法中使用
//    public static void func2(){
//        System.out.println(super.a);//error
//        System.out.println(this.a);//error
//    }@Overridepublic void doSomething(){//子类对父类函数发生重写System.out.println("狗,汪汪叫!");}public void eat(){//构成对父类的隐藏:其实就是优先访问自己的System.out.println("Dog eat!");}public void eat(int x){//和eat参数列表不同构成重载.既和子类的构成重载,和父类的也构成重载.继承下来的也认为是一个作用域System.out.println(x+ "Dog eat!");}
}
class Cat extends Animal{}
public class inherit {//继承public static void main(String[] args) {Dog dog =new Dog();dog.name="狗";dog.age=22;Cat cat=new Cat();cat.age=10;cat.name="猫";dog.eat();dog.eat(2);Animal a1= new Animal();a1.doSomething();//父类的引用调用子类发生重写的函数,构成多态Animal a2 =new Dog();a2.doSomething();dog.func();}
}
构造方法
class Base{public String name;public int age;public Base(){//提供默认构造函数之后才行}public Base(String name,int a ) {//当只提供这个构造函数时,子类无法创建this.name = name;this.age=a;}
}
class Derive extends Base{
}
class C{public String name;public int age;public C(String name,int a ) {//当只提供这个构造函数时,子类无法创建this.name = name;this.age=a;}
}
class D extends C{public D(String name,int age){super(name,age);//并没有在这里构造一个父类对象,只是将继承下来的成员变量进行初始化
//        super("yuanwei",22);//显示的调用父类构造函数,帮助父类成员完成初始化}
}class E extends C{int e=0;public E(String name,int age){super(name,age);//一定要先帮助父类初始化e=20;}public E(String name,int age,int e){super(name,age);
//        this(name,age,e);//this 和super顺序无法确定,所以在调用构造方法时不能同时出现}
}
class G{}
class H extends G{//什么都不写,编译器默认生成如下代码public H(){super();//调用父类自动生成的构造函数}
}
super和this的区别

super和this都可以在成员方法中用来访问,

成员变量和调用其他的成员函数都可以作为构造方法的第一条语句

  • 那他们之间有什么区别呢?

[相同点]

1.都是]ava中的关键字
2.只能在类的非静态方法中使用,用来访问非静态成员方法和字段
3.在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

[不同点]

1.this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分员的引用

2.在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性

3.在构造方法中: this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现

4.构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有.

代码块构造顺序
class Y{static{System.out.println("Y : static 静态代码块");}{System.out.println("Y: 非静态代码块");}Y() {System.out.println("Y : 不带参数的构造函数");}
}
class W extends Y{static{System.out.println("W : static 静态代码块");}{System.out.println("W: 非静态代码块");}W() {System.out.println("W : 不带参数的构造函数");}public static void main(String[] args) {W w=new W();//Y : static 静态代码块//W : static 静态代码块//Y: 非静态代码块//Y : 不带参数的构造函数//W: 非静态代码块//W : 不带参数的构造函数System.out.println("==============");W w1=new W();//Y: 非静态代码块//Y : 不带参数的构造函数//W: 非静态代码块//W : 不带参数的构造函数}
}
  • 先静态,先父类静态再子类静态.再父类实例和构造函数,子类实例和构造函数
  • 静态每一个类,只会执行一次
限定修饰符

protected: 不同包的子类可以使用

default:同一包中不同的类可以使用

private: 修饰只能在同一个类中才能访问

image-20231020155538822

class V{private String name;public void func(){System.out.println(name);}
}
class N extends V{public static void main(String[] args) {
//        System.out.println(name);//error//private修饰的name已经被继承了,但是不可见. 因为private修饰只能在同一个类中才能访问}
}
final
//继承的深度可能很深,为了避免深度过深,当不想某一个类被继承时 ,使用final关键字
class a{public final int b=20;//成员变量定义为final一定要给定初始值
}
class b extends a{public static void main(String[] args) {final int[] array={1,2,3,4,5};array[0]=10;
//        array =new int[4]{2,3,4,5};//Cannot assign a value to final variable 'array'//array指向的对象是不能改变的}
}
final class c extends b{//不想让C被继承public static void main(String[] args) {final int A=10;
//        A=20;//error不想让A 被修改,那就是常量,建议大写变量名System.out.println(A);}
}
//class d extends c{//error
//
//}
继承和组合

是一种代码实现方式,设计思想. a part of ; has a 的关系.

降低不同类耦合度.

奔驰是一辆车

奔驰有轮胎,座椅,车架子这些类.

多态

同一件事情,发生在不同对象的身上,呈现出不同的状态.

  • 子类对父类对象中方法重写
  • 父类引用调用子类对象
向上转型
  • 子类对象给父类,使得父类引用指向了子类对象.
  • 因为父子类继承关系,所以可以实现不同类型对象之间的赋值.
  • 当发生向上转型之后,父类的引用,只能,访问父类自己的成员,不能访问子类所特有的成员.

class Animal {public String name;public void eat(){System.out.println(name+" 吃!");}
}
class Bird extends Animal {public String swing="翅膀";public void fly(){System.out.println(name+" 用 "+swing+" 飞 ");}
}
class Pig extends Animal{public int iq=1000;public void poll(){System.out.println(name + " 的iq是 "+iq);}
}public class PolyCode {//返回值统一public static Animal func2(){Bird bird = new Bird();bird.name="鸟";Pig pig=new Pig();pig.name="猪";return pig;}//函数传参中的向上转型public static void  func(Animal animal){//使用父类引用进行接收子类对象,也是一种向上转型System.out.println(animal.name);}public static void main(String[] args) {Bird bird = new Bird();bird.name="鸟";func(bird);Pig pig=new Pig();pig.name="猪";func(pig);//鸟//猪}//直接接收public static void main1(String[] args) {Animal a=new Animal();a.name="动物基类";a.eat();System.out.println("=================");Animal a2=new Pig();a2.name="猪";a2.eat();((Pig) a2).poll();//这么写可以,但是不建议
//        a2.poll();//error,子类中包含父类中没有的方法和属性System.out.println("=================");Animal a3 = new Bird();a3.name="鸟";a3.eat();((Bird) a3).fly();//动物基类 吃!//=================//猪 吃!//猪 的iq是 1000//=================//鸟 吃!//鸟 用 翅膀 飞}
}
重写

需要满足三同: 函数名相同,参数列表相同,返回值相同.

class Animal {public String name;public void eat(){System.out.println(name+" 吃!");}
}
class Bird extends Animal {public String swing="翅膀";@Overridepublic void eat(){System.out.println(name+" 吃!");}
}
class Pig extends Animal{public int iq=1000;@Overridepublic void eat(){System.out.println(name+" 吃!");}
}
public class PolyCode {public static void main(String[] args) {Animal a=new Animal();a.name="动物基类";a.eat();System.out.println("=================");Animal a2=new Pig();a2.name="猪";a2.eat();System.out.println("=================");Animal a3 = new Bird();a3.name="鸟";a3.eat();//动物基类 吃!//=================//猪 吃!//=================//鸟 吃!}
}
动态绑定

image-20231021201204625

在编译时发现是没有变化的,每个类的函数都会被确定执行地址.只有在运行时才会根据类型的不同,实现函数地址覆盖,然后调用.

import javafx.scene.image.PixelFormat;
class Animal {public String name;public void eat(){System.out.println(name+" 吃!");}
}
class Bird extends Animal {public String swing="翅膀";@Overridepublic void eat(){System.out.println(name+" 吃!");}
}
class Pig extends Animal{public int iq=1000;@Overridepublic void eat(){System.out.println(name+" 吃!");}
}
public class PolyCode {//多态: 当父类引用的对象不同时,表现出来的行为是不一样的public static void function(Animal animal){animal.eat();}public static void main(String[] args) {Animal a=new Animal();a.name="动物基类";function(a);System.out.println("=================");Animal a2=new Pig();a2.name="猪";function(a2);System.out.println("=================");Animal a3 = new Bird();a3.name="鸟";function(a3);}
重写注意事项
  1. private修饰的函数是不能被重写的

  2. static修饰的不能被重写.这个方法属于这个类不属于某个对象

  3. 子类的访问修饰限定权限要>=父类的.

    private<default<protected<public

  4. 被final修饰的方法是不能被重写的.此时这个方法被称为密封方法.

向下转型

子类引用指向父类对象.

非常的不安全,只能骗过编译器,但是运行时会出现问题

import javafx.scene.image.PixelFormat;
class Animal {public String name;public void eat(){System.out.println(name+" 吃!");}
}
class Bird extends Animal {public String swing="翅膀";@Overridepublic void eat(){System.out.println(name+" 吃!");}
}
class Pig extends Animal{public int iq=1000;@Overridepublic void eat(){System.out.println(name+" 吃!");}public void poll(){System.out.println(name + " 的iq是 "+iq);}
}
public class PolyCode {//向下转型: 所有的动物一定都是猪吗?public static void main(String[] args) {Animal animal =new Bird();//1.Pig pig =(Pig) animal;pig.poll();//terminal animal最开始是Bird的引用,又强转为pig,Bird中没有poll方法//2.//需要通过instanceof关键字判断animal是否真的引用一个pig对象if(animal instanceof Pig){Pig pig2 = (Pig)animal;pig2.poll();}}
}
多态优点
  1. 降低圈复杂度,避免使用大量的if-else判断语句.
  2. 父类类型数组可以存放子类的对象.
import javafx.scene.image.PixelFormat;
class Shape{public String name;public void drawShape(){System.out.println("画");}
}
class Circle extends Shape{public void drawShape(){System.out.println("画圆");}
}
class Rect extends Shape{public void drawShape(){System.out.println("画矩形");}
}
class Flower extends Shape{public void drawShape(){System.out.println("画花");}
}
public class PolyCode {public static void draw(){Rect rect=new Rect();Circle circle =new Circle();Flower flower =new Flower();//此处发生向上转型Shape[] shape = new Shape[]{rect,circle,flower};for(Shape e: shape){e.drawShape();}//画矩形//画圆//画花}public static void main(String[] args) {draw();}
}
注意
  1. 避免在构造方法中调用重写方法

当在父类中的构造方法中,调用父类和子类发生重写的 方法时,会调用子类的.

导致父类构造函数都没走完,父类对象都没有初始化完成,自然子类对象也没有初始化完成,所有的成员都是默认值.

import javafx.scene.image.PixelFormat;
//-------------避免在构造函数中调用重写函数
class B{public B(){func();}public void func(){System.out.println("B::func()");}
}
class D extends B{private int num=1;//默认调用B类的构造函数
//    D(){
//        super();
//    }public void func(){System.out.println("D::func()");System.out.println("B.num = "+num);}
}public class PolyCode{public static void main(String[] args) {D d=new D();//D::func()//B.num = 0}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KDE 项目发布了 KDE Gear 23.08.3

导读KDE 项目发布了 KDE Gear 23.08.3&#xff0c;作为最新的 KDE Gear 23.08 开源集合的第三次维护更新&#xff0c;该集合包含了用于 KDE Plasma 桌面环境和其他平台的 KDE 应用程序。 KDE Gear 23.08.3 是在 KDE Gear 23.08.2 大约一个月之后发布的&#xff0c;包含了更多对…

系列五、为什么不用线程id作为ThreadLocalMap的key

一、为什么不用线程id作为ThreadLocalMap的key 1.1、案例代码 /*** Author : 一叶浮萍归大海* Date: 2023/11/21 11:50* Description: 需求&#xff1a;* 如果当前线程是线程1&#xff0c;那么设置书名和作者分别为 三国演义 罗贯中* 如果…

“高校评分”走红网络,虎扑:若造谣抹黑,学校可联系平台处理

哎呀&#xff0c;最近虎扑APP的全国高校评分可是火遍了网络啊&#xff01;那些机智的评语&#xff0c;哦哟&#xff0c;都成了新的“网络爆款梗”&#xff01;有毕业生说嘛&#xff0c;这评分都是看学生自己的经历和感受&#xff0c;有好评当然就有差评啦。但关键是&#xff0c…

Django 入门学习总结3

1、创建数据库 打开mysite/settings.py文件&#xff0c;可以看到我们使用Python中已包含的默认的数据库SQLite&#xff0c;也可以使用其他的数据库&#xff0c;如Oracle、Mysql等。里面也包含时区、语言等设置信息。 在使用数据库和表之前&#xff0c;输入下面的命令&#xf…

HT5169 单声道D类音频功放 I2S输入

HT5169是一款内置BOOST升压模块的D类音频功率放大器。内置的BOOST升压模块可通过外置电阻调节升压值&#xff0c;即使是锂电池供电&#xff0c;在升压至7.5V&#xff0c;2Ω负载条件下则能连续输出 11W功率。其支持外部设置调节BOOST输出电压。 HT5169是一颗单声道D类音频功放&…

Android使用Kotlin利用Gson解析多层嵌套Json数据

文章目录 1、依赖2、解析 1、依赖 build.gradle(app)中加入 dependencies { implementation com.google.code.gson:gson:2.8.9 }2、解析 假设这是要解析Json数据 var responseStr "{"code": 200,"message": "操作成功","data&quo…

A____Z____RECOVER____DATA勒索恢复---惜分飞

有客户MySQL数据库被黑,业务库中表被删除,并创建A____Z____RECOVER____DATA库,里面有一张readme表,内容为: mysql> select * from readme \G; *************************** 1. row *************************** zh_content: 请尽快与我们取得联系&#xff0c;否则我们将会公…

第28期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

【linux】进行间通信——共享内存+消息队列+信号量

共享内存消息队列信号量 1.共享内存1.1共享内存的原理1.2共享内存的概念1.3接口的认识1.4实操comm.hppservice.cc &#xff08;写&#xff09;clint.cc &#xff08;读&#xff09; 1.5共享内存的总结1.6共享内存的内核结构 2.消息队列2.1原理2.2接口 3.信号量3.1信号量是什么3…

如何开发干洗店用的小程序

洗护行业现在都开始往线上的方向发展了&#xff0c;越来越多的干洗店都推出了上门取送服务&#xff0c;那么就需要开发一个干洗店专用的小程序去作为用户和商家的桥梁&#xff0c;这样的小程序该如何开发呢&#xff1f; 一、功能设计&#xff1a;根据干洗店的业务需求和小程序的…

算法-二叉树-简单-二叉树的直径、将有序数组转换成二叉搜索树

记录一下算法题的学习9 二叉树的直径 题目&#xff1a;给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。两节点之间路径的 长度 由它们之间边数表示 读完题目&…

2014年3月24日 Go生态洞察:Go地鼠的故事

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

PRD学习

产品经理零基础入门&#xff08;五&#xff09;产品需求文档PRD&#xff08;全16集&#xff09;_哔哩哔哩_bilibili 1. PRD的2种表现形式 ① RP格式 &#xff08;1&#xff09;全局说明 ② 文档格式

redis之主从复制和哨兵模式

&#xff08;一&#xff09;redis的性能管理 1、redis的数据缓存在内存中 2、查看redis的性能&#xff1a;info memory&#xff08;重点&#xff09; used_memory:904192&#xff08;单位字节&#xff09; redis中数据占用的内存 used_memory_rss:10522624 redis向操作系统…

广告行业中那些趣事系列66:使用chatgpt类LLM标注数据并蒸馏到生产小模型

导读&#xff1a;本文是“数据拾光者”专栏的第六十六篇文章&#xff0c;这个系列将介绍在广告行业中自然语言处理和推荐系统实践。本篇主要介绍使用chatgpt类LLM进行数据标注任务并蒸馏到生产小模型&#xff0c;对于希望使用chatgpt类LLM进行打标并部署到生产任务中的小伙伴可…

JVM的垃圾收集算法

1.算法的分类 1.1标记清除算法 第一步&#xff1a;标记&#xff08;找出内存中需要回收的对象&#xff0c;并且把它们标记出来&#xff09; 根据可达性算法&#xff0c;标记的是存活的对象&#xff0c;然后将其他的空间进行回收 第二步&#xff1a;清除&#xff08;清除掉被…

Sentinel 监控数据持久化(mysql)

Sentinel 实时监控仅存储 5 分钟以内的数据&#xff0c;如果需要持久化&#xff0c;需要通过调用实时监控接口来定制&#xff0c;即自行扩展实现 MetricsRepository 接口&#xff08;修改 控制台源码&#xff09;。 本文通过使用Mysql持久化监控数据。 1.构建存储表&#xff08…

ESP32 Arduino实战Web篇-使用 WebSocket 创建 ESP32 Web 服务器

本文将详细介绍如何使用 WebSocket 创建 ESP32 Web 服务器,解释WebSocket原理与搭建步骤,并附超详细的代码解释 假设我们需要创建一个使用 ESP32 通过 WiFi 控制灯泡的项目。实现非常简单:我们将 ESP32 设置为软 AP 或 STA 模式,使其能够提供一个网页,显示灯开关的状态为…

HT560 30W 过温限幅 D类音频功率放大器

HT560具有过温限幅功能&#xff0c;当芯片内部温度达到过温限幅点&#xff0c;HT560自动降低增益&#xff0c;使其IC能够连续播放而不间断。另外&#xff0c;HT560具有功率限制功能&#xff0c;一种是限幅功能&#xff0c;在输出端限制一定的输出幅度&#xff0c;使其不损坏喇叭…

阿里云高效计划学生和老师免费代金券申请认证方法

阿里云高校计划学生和教师均可参与&#xff0c;完成学生认证和教师验证后学生可以免费领取300元无门槛代金券和3折优惠折扣&#xff0c;适用于云服务器等全量公共云产品&#xff0c;订单原价金额封顶5000元/年&#xff0c;阿里云百科aliyunbaike.com分享阿里云高校计划入口及学…