Java学习笔记(13)——面向对象编程

news2024/12/20 12:38:46

面向对象基础

目录

面向对象基础

方法重载

练习:

继承

继承树

protected

super

阻止继承

向上转型

向下转型

区分继承和组合

练习

小结:


方法重载

如果有一系列方法,功能类似,只是参数有所不同,就可以把这字方法名成同名方法:

class Hello {
    public void hello() {
        System.out.println("Hello");
    }

    public void hello(String name) {
        System.out.println("Hello " + name);
    }

    public void hello(String name,int age) {
        if(age < 18) {
            System.out.println("Hi " + name + "!");
        } else {
            System.out.println("Hello " + name + "!");
        }
    }
}

这种方法名相同,但各自参数不同,称为方法重载(Overload)。

通常,方法重载的返回值类型都是相同的。

举个例子:

String类提供了多个重载方法indexOf(),可以查找子串:

  • int indexOf(int ch):根据字符的Unicode码查找
  • int indexOf(String str):根据字符查找
  • int indexOf(int ch,int fromIndex):指定起始位置,根据字符查找
  • int indexOf(String str,int fromIndex):指定起始位置,根据字符串查找
public class Main {
    public static void main(String[] args) {
        String s = "Test string";
        int n1 = s.indexOf('t');
        int n2 = s.indexOf("st");
        int n3 = s.indexOf("st",4);
        System.out.println(n1);
        System.out.println(n2);
        System.out.println(n3);
    }
}

练习:

public class Main {
    public static void main(String[] args) {
        Person ming = new Person();
        Person hong = new Person();
        ming.setName("Xiao Ming");
        hong.setName("Xiao ","Hong");
        System.out.println(ming.getName());
        System.out.println(hong.getFirstName() + hong.getSunName());
    }
}

class Person {
    private String name;
    private String sunName;
    private String firstName;

    public String getName() {
        return name;
    }
    public String getSunName() {
        return sunName;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setName(String name) {
        this.name = name;
    }

    public void setName(String fitstName,String sunName) {
        this.firstName = fitstName;
        this.sunName = sunName;

    }
}

继承

若要定义一个类,这个类包含了已有类的字段和方法,只是增加了一些字段和方法,可以用继承从而在这个类中不写重复代码。

继承是面向对象编程中非常强大的一种机制,可以复用代码,只需要为新的类编写新增功能即可。

Java用extends关键字来实现继承:

class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

class Student extends Person {
    private int score;
    public void getScore(int score) {
        this.score = score;
    }
}

子类自动获得了父类所有字段,严禁定义与父类重名的字段。

在OOP的术语中,把Person成为超类,基类,父类;把Student成为子类,扩展类

继承树

在Java中 ,没有明确写extends的类,编译器自动加上extends Object。所以,除了Object,任何类都会继承自某个类,Java只允许一个class继承自一个类。

protected

继承的特点:子类无法访问父类的private字段或者private方法。所以下面例子中Student无法访问Person的name字段和age字段:

class Person {
    private String name;
    private int age;
}

class Student extends Person {
    public String hello() {
        return "Hello," + name;//会编译错误
    }
}

为了让子类可以访问父类的字段,要把private改为protected。用protected修饰的字段可以被子类访问。

class Person {
    protected String name;
    protected int age;
}

class Student extends Person {
    public String hello() {
        return "Hello," +name;//可以正常编译
    }
}

以上,protected关键字可以把字段和方法的访问权限控制在继承树内部,一个protected字段和方法可以被其子类、子类的子类访问。

super

表示父类(超类)。子类引用父类的字段时,可以用super.fieldName。例如:

class Student extends Person {
    public String hello() {
        return "Hello," + super.name;
    }
}

这里使用super.name或者this.name效果一致,编译器会自动定位到父类的name字段。

但是,在某些情况,必须使用super,如:

public class Main {
    public static void main(String[] args) {
        Student s = new Student("Xiao Ming",12,89);
    }
}

class Person {
    protected String name;
    protected int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

}

class Student extends Person {
    protected int score;
    public Student(String name,int age,int score) {
        this.score = score;
    }
}

编译错误为:在Student的构造方法中,无法调用Person的构造方法。

在Java中,任何class的构造方法,第一行语句必须是调用父类的构造方法,编译器会自动加一个super·();所以,Student类的构造方法实际是这样:

class Student extends Person {
    protected int score;
    public Student(String namekint age,int score; {
        super();
        this.score = score;
    }
}

由于Person类并没有无参数的构造方法,所以编译失败,可以调用Person存在的某个构造方法,如:

class Student extends Person {
    protected int score;
    public Student(String name,int age,int score) {
        super(name,age);
        this.score = score;
    }
}

结论:如果父类没有默认构造方法,子类就必须显示调用super()并给出参数以便编译器定位到父类的一个合适的构造方法。子类不会继承父类的任何构造方法,子类默认的构造方法是编译器自动生成的,而不是继承的。

阻止继承

正常情况下,只要某个类没有final修饰符,那么任何类都可以从该class继承。用sealed修饰class,并通过permits明确写出能够从该class类继承的子类名称。

比如定义一个Shape类:

public sealed class Shape permits Rect,Circle,Triangle {
    ...
}

这就是一个sealed类,只允许指定的3个类继承它,

public final class Rect extends Shape{...}
// 没问题,因为Rect出现在Shape的permits列表中
// 但是,如果定义一个Ellipse就会报错
// 因为Ellipse并未出现在Shape的permits列表中。
public final class Sllipse extends Shape {...}
// Compile error: class is not allowed to extend sealed class: Shape

这种sealed类主要用于一些框架,防止继承被滥用。

sealed在Java15中目前是预览状态,要启用它必须使用参数--enable-preview和--source15

向上转型

如果Student是Person继承下来的,那么,一个引用类型为Person的变量,可以指向Student。Student拥有父类Person所有功能,Person类型的变量可以指向Student类型的实例。

Person p = new Student();

这种把一个子类类型安全的变为父类类型的赋值,被称为向上转型(upcasting)

Student s = new Student();
Person p = s;// upcasting,ok
Object o1 = p;// upcasting,ok
Object o2 = s;// upcasting,ok

继承树为:Student > Person > Object,所以,可以把Student类型转为Person或Object

向下转型

如果一个父类类型强制转为子类类型,就是向下转型(downcasting)

Person p1 = new Student();// upcasting,ok
Person p2 = new Person();
Student s1 = (student) p1;// ok
Student s2 = (Student) p2;// runtime error! ClassCastException!

为了避免向下转型出现错误Java提供了instanceof操作符,可以先判断一个实例究竟是不是某种类型。

Person p = new Person();
System.out.println(p instancaof Person);// true
System,out.ptintln(p instanceof Student);// false

Student s = new Student();
System.out.println(s instanceof Person);// true
System.out.println(s instanceof Student);// true


Student n = null;
System.out.println(n instanceof Student);ture

instanceof实际上判断一个变量所指的实例是否是指定类型,或者这个类型的子类。如果一个引用变量为null,那么对任何instanceof的判断都为false

利用instanceof,在向下转型前可以先判断:

Person p = new Student();
if (p instanceof Student) {
    // 只有判断成功才会向下转型
    Student s = (Student) p;
}

从Java14开始,判断instanceof后,可以直接转型为指定变量,避免再次强制转型。

Object obj = "hello";
if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.toUpperCase());
}
// 可以改写为:
public class Main {
    public static void main(String[] args) {
        Object obj = "hello";
        if(obj instanceof String s) {
            // 直接使用变量s
            System.out.println(s.yoUpperCase());
        }
    }
}

区分继承和组合

is关系用继承,has关系用组合:

class Student extends Person {
    protected Book book;
    protected int score;
}

练习

public class Main {
    public static void main(String[] args) {
        Person p = new Person("小明",12);
        Student s = new Student("小红",29,99);
        Student ps = new PrimaryStudent("小军",9,100,5);
        System.out.println(ps.getScore());
    }
}

class Person {
    protected String name;
    protected int age;

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

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

class Student extends Person {
    protected int score;

    public Student(String name, int age, int score) {
        super(name, age);
        this.score = score;
    }

    public int getScore() {
        return score;
    }
}

class PrimaryStudent extends Student {
    protected int grade;
    public PrimaryStudent(String name, int age, int score, int grade) {
        super(name, age, score);
    }
}

小结:

继承是面向对象编程的一种强大的代码复用方式。

只允许单继承,所有类最终的根类是Object

protected允许子类访问父类的字段和方法

子类的构造方法可以通过super()调用父类的构造方法

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

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

相关文章

Running CMake (运行 CMake)

Running CMake {运行 CMake} 1. CLion - Create a new CMake project2. Running CMake (运行 CMake)2.1. Building a project (构建项目)2.2. Picking a compiler (指定编译器)2.3. Verbose and partial builds (详细和部分的构建)2.4. Options (选项)2.4.1. Standard options …

穷举vs暴搜vs深搜vs回溯vs剪枝专题一>子集

题目&#xff1a; 两个方法本质就是决策树的画法不同 方法一解析&#xff1a; 代码&#xff1a; class Solution {private List<List<Integer>> ret;//返回结果private List<Integer> path;//记录路径&#xff0c;注意返回现场public List<List<Int…

MTU 使用使用解释

MTU (Maximum Transmission Unit&#xff0c;最大传输单元) 指的是网络链路层 (例如以太网) 能够传输的最大数据帧大小&#xff0c;以字节为单位。理解 MTU 对网络性能和可靠性至关重要&#xff0c;因为它直接影响数据包的分片 (Fragmentation) 和重组。本文档将详细解释 MTU 的…

uniapp v-tabs修改了几项功能,根据自己需求自己改

根据自己的需求都可以改 这里写自定义目录标题 1.数组中的名字过长&#xff0c;导致滑动异常2.change 事件拿不到当前点击的数据&#xff0c;通过index在原数组中查找得到所需要的id 各种字段麻烦3.添加指定下标下新加红点显示样式 1.数组中的名字过长&#xff0c;导致滑动异常…

iOS - 超好用的隐私清单修复脚本(持续更新)

文章目录 前言开发环境项目地址下载安装隐私访问报告隐私清单模板最后 前言 在早些时候&#xff0c;提交应用到App Store审核&#xff0c;大家应该都收到过类似这样的邮件&#xff1a; Although submission for App Store review was successful, you may want to correct th…

c语言-----数组

基本概念 数组是C语言中一种用于存储多个相同类型数据的数据结构。这些数据在内存中是连续存储的&#xff0c;可以通过索引&#xff08;下标&#xff09;来访问数组中的各个元素。数组的索引从0开始&#xff0c;这是C语言的规定。例如&#xff0c;一个有n个元素的数组&#xff…

社区版 IDEA 开发webapp 配置tomcat

1.安装tomcat 参考Tomcat配置_tomcat怎么配置成功-CSDN博客 2.构建webapp项目结构 新建一个普通项目 然后添加webapp的目录结构&#xff1a; main目录下新建 webapp 文件夹 webapp文件夹下新建WEB_INF文件夹 *WEB_INF目录下新建web.xml wenapp文件夹下再新建index.html …

全面解析 Kubernetes 流量负载均衡:iptables 与 IPVS 模式

目录 Kubernetes 中 Service 的流量负载均衡模式 1. iptables 模式 工作原理 数据路径 优点 缺点 适用场景 2. IPVS 模式 工作原理 数据路径 优点 缺点 适用场景 两种模式的对比 如何切换模式 启用 IPVS 模式 验证模式 总结 Kubernetes 中 Service 的流量负载…

C 语言数据类型详解

目录 一、引言 二、基本数据类型 &#xff08;一&#xff09;整型 &#xff08;二&#xff09;浮点型 &#xff08;三&#xff09;字符型 三、构造数据类型 &#xff08;一&#xff09;数组 &#xff08;二&#xff09;结构体 &#xff08;三&#xff09;联合体&#…

Python图注意力神经网络GAT与蛋白质相互作用数据模型构建、可视化及熵直方图分析...

全文链接&#xff1a;https://tecdat.cn/?p38617 本文聚焦于图注意力网络GAT在蛋白质 - 蛋白质相互作用数据集中的应用。首先介绍了研究背景与目的&#xff0c;阐述了相关概念如归纳设置与转导设置的差异。接着详细描述了数据加载与可视化的过程&#xff0c;包括代码实现与分析…

LeetCode 1925 统计平方和三元组的数目

探索平方和三元组&#xff1a;从问题到 Java 代码实现 在数学与编程的交叉领域&#xff0c;常常会遇到一些有趣且富有挑战性的问题。今天&#xff0c;就让我们深入探讨一下 “平方和三元组” 这个有趣的话题&#xff0c;并使用 Java 语言来实现计算满足特定条件的平方和三元组…

回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测

回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效…

vue横向滚动日期选择器组件

vue横向滚动日期选择器组件 组件使用到了element-plus组件库和dayjs库&#xff0c;使用前先保证项目中已经下载导入 主要功能&#xff1a;选择日期&#xff0c;点击日期可以让此日期滚动到视图中间&#xff0c;左滑右滑同理&#xff0c;支持跳转至任意日期&#xff0c;支持自…

Firecrawl教程①:自动化抓取与数据转化,赋能AI应用

Firecrawl教程①:自动化抓取与数据转化,赋能AI应用 前言一、功能特点1. 支持 LLM 可处理的数据格式2. 全面抓取网站3. 强大的操作支持4. 灵活的定制选项5. 支持多种编程语言 SDK二、如何开始使用 Firecrawl第一步:获取 API 密钥第二步:官网在线工具使用第三步:安装 Firecr…

WatchAlert - 开源多数据源告警引擎

概述 在现代 IT 环境中&#xff0c;监控和告警是确保系统稳定性和可靠性的关键环节。然而&#xff0c;随着业务规模的扩大和数据源的多样化&#xff0c;传统的单一数据源告警系统已经无法满足复杂的需求。为了解决这一问题&#xff0c;我开发了一个开源的多数据源告警引擎——…

svn版本丢失导致无法访问临时解决方法

#svn异常问题# 在使用svn的过程中&#xff0c;有时候在数据量比较大的情况下&#xff0c;有涉及到数据迁移或者是文件移动操作时容易出现迁移过程中有人还提交了数据&#xff0c;导致迁移的数据出现版本丢失的情况。 比如说&#xff0c;我实际遇到的情况是迁移数据的时候记录…

0009.基于springboot+layui的ERP企业进销存管理系统

一、系统说明 基于springbootlayui的ERP企业进销存管理系统,系统功能齐全, 代码简洁易懂&#xff0c;适合小白学编程,课程设计&#xff0c;毕业设计。 二、系统架构 前端&#xff1a;html| layui 后端&#xff1a;springboot | mybatis| thymeleaf 环境&#xff1a;jdk1.8 |…

Latex+VsCode+Win10搭建

最近在写论文&#xff0c;overleaf的免费使用次数受限&#xff0c;因此需要使用本地的形式进行编译。 安装TEXLive 下载地址&#xff1a;https://mirror-hk.koddos.net/CTAN/systems/texlive/Images/ 下载完成直接点击iso进行安装操作。 安装LATEX Workshop插件 设置VsCode文…

[创业之路-199]:《华为战略管理法-DSTE实战体系》- 3 - 价值转移理论与利润区理论

目录 一、价值转移理论 1.1. 什么是价值&#xff1f; 1.2. 什么价值创造 &#xff08;1&#xff09;、定义 &#xff08;2&#xff09;、影响价值创造的因素 &#xff08;3&#xff09;、价值创造的三个过程 &#xff08;4&#xff09;、价值创造的实践 &#xff08;5&…

如何在单选按钮中添加图标和文字

文章目录 1. 概念介绍2. 使用方法3. 示例代码我们在上一章回中介绍了Radio Widget相关的内容,本章回中将介绍RadioListTile Widget.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在这里介绍的RadioListTile和上一章回中介绍的Radio类似,不同之处在于RadioListTile组…