Java 多态、包、final、权限修饰符、静态代码块

多态

Java多态是指一个对象可以具有多种形态。它是面向对象编程的一个重要特性,允许子类对象可以被当作父类对象使用。多态的实现主要依赖于继承、接口和方法重写。

在Java中,多态的实现主要通过以下两种方式:

  1. 继承:子类继承父类的属性和方法,可以对方法进行重写(覆盖),从而实现不同的行为。

  2. 接口:类可以实现一个或多个接口,从而拥有接口中定义的方法。接口中的方法默认是抽象的,需要类来实现。

下面是一个简单的Java多态示例:

// 父类
class Animal {public void makeSound() {System.out.println("动物发出声音");}
}// 子类
class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("狗汪汪叫");}
}// 子类
class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("猫喵喵叫");}
}public class Main {public static void main(String[] args) {// 使用父类引用指向子类对象,实现多态Animal myAnimal = new Dog();myAnimal.makeSound(); // 输出:狗汪汪叫myAnimal = new Cat();myAnimal.makeSound(); // 输出:猫喵喵叫}
}

在这个示例中,DogCat 类都继承了 Animal 类,并重写了 makeSound 方法。在 main 方法中,我们使用父类 Animal 的引用来指向子类 DogCat 的对象,实现了多态。当我们调用 makeSound 方法时,会根据实际对象的类型来执行相应的方法。

核心要素

多态的存在依赖于三个核心要素:

  1. 继承:多态的实现基于类的继承关系。这意味着必须有一个父类和至少一个子类,子类从父类那里继承了某些属性和方法。
  2. 方法重写:在子类中对继承自父类的方法进行重写(覆盖)。这样,当调用这些方法时,可以根据对象的实际类型(父类或子类)来执行相应的方法版本。
  3. 父类引用指向子类对象:使用父类类型的引用来指向子类的对象实例。这使得可以通过父类引用来操作子类对象,实现在不同子类对象上执行相同的操作,但表现出不同的行为。

此外,多态性通常与方法有关,与类的属性无关。这是因为多态性主要关注通过同一个接口(父类引用)调用不同类(子类)中的方法时,如何根据对象的实际类型来执行相应的方法版本。

 多态的弊端

多态在面向对象编程中是一种强大的特性,它允许不同类的对象对同一消息做出响应。然而,尽管多态性提高了代码的灵活性和可维护性,但它也有一些弊端。具体来说,多态的弊端主要包括以下几点:

  • 不能直接使用子类的特有属性和行为:当使用父类引用指向子类对象时,只能访问到父类中定义的属性和方法,而不能直接访问子类特有的属性和方法。这是因为在多态的情况下,编译器只知道该引用是父类类型,而不知道具体是哪个子类的实例。
  • 需要进行向下转型(强制类型转换):为了能够访问子类特有的属性和方法,需要将父类引用显式地转换为子类类型,这个过程称为向下转型。然而,向下转型可能会带来风险,如果转型的类型不正确,就会抛出ClassCastException异常。
  • 可能导致设计上的问题:过度依赖多态可能会导致设计上的问题,例如破坏了封装性,因为需要在外部代码中进行类型转换,这可能会增加代码的复杂性和出错的可能性。

 instanceof 关键字

instanceof是Java中的一个关键字,用于检查一个对象是否属于某个类或接口的实例。它的语法格式为:

object instanceof ClassName

其中,object是要检查的对象,ClassName是要检查的类或接口的名称。如果objectClassName的实例,那么表达式的结果为true,否则为false

例如,假设我们有一个名为Animal的类和一个名为Dog的子类,我们可以使用instanceof来检查一个对象是否是AnimalDog的实例:

Animal animal = new Animal();
Dog dog = new Dog();if (animal instanceof Animal) {System.out.println("animal 是 Animal 的实例");
}if (dog instanceof Animal) {System.out.println("dog 是 Animal 的实例");
}if (dog instanceof Dog) {System.out.println("dog 是 Dog 的实例");
}

输出结果为:

animal 是 Animal 的实例
dog 是 Animal 的实例
dog 是 Dog 的实例

 包

Java 包是一种命名空间,用于将类和接口进行分组管理,它有助于提高代码的可读性、查找效率以及控制访问权限。以下是关于Java包的一些基本信息:

  1. 概念:Java 包是组织类和接口的一种机制,它可以防止命名冲突,并且有助于管理大型项目中的代码。
  2. 声明:在Java文件中,使用package关键字来声明一个包。例如,package com.example;表明该文件属于com.example这个包。
  3. 导入:要使用其他包中的类,可以使用import关键字来导入。例如,import java.util.List;表示导入了java.util包下的List类。
  4. 作用域:包的作用域决定了类和接口的可见性。默认情况下,类和接口的访问级别是包私有的,即只有相同包内的其他类可以访问。
  5. 命名规范:包的命名通常采用全小写字母,并使用点号.分隔不同的名称层级,如com.example.myapp。这种命名方式有助于避免与标准Java类库的名称冲突,并且反映了组织的域名结构。
  6. 创建包:在IDE(如IntelliJ IDEA)中,可以通过右键点击项目目录结构来创建新的包。然后,可以在新包中创建类和其他资源。
  7. 访问方法:要访问不同包中的类,可以使用类的完全限定名(包括包名和类名),或者通过import语句导入后直接使用类名。
  8. 注意事项:在设计包结构时,应该考虑到代码的逻辑分组和功能划分,以便于维护和扩展。同时,避免创建过于庞大或过于细化的包,以免造成管理上的不便。

Java 包是管理Java代码的一个重要工具,它不仅能够帮助开发者组织代码结构,还能够提供访问控制和命名空间的管理功能。在大型项目中,合理地使用包可以大大提高代码的可维护性和可读性。

 fianl 关键字

final关键字在Java中确实扮演着重要的角色,它可以用来修饰类、方法和变量,下面是对这些用途的详细介绍:

  1. 修饰类:当一个类被声明为final时,它不能被继承。这通常用于那些包含核心功能且不希望被修改的类。例如,Java中的String类就是一个final类,因为它的设计不允许更改其核心行为。
    final class FinalClass {// 该类不能被继承
    }// class SubFinalClass extends FinalClass { // 错误,无法继承final类
    //     // ...
    // }
  2. 修饰方法final方法不能被子类重写。这通常用于确保某些方法的行为在子类中保持一致,或者出于安全考虑,防止子类改变其行为。
    class MyClass {public final void printMessage() {System.out.println("This is a final method.");}
    }class SubClass extends MyClass {// 无法重写父类的final方法// public void printMessage() {//     System.out.println("Cannot override final method.");// }
    }
  3. 修饰成员变量:成员变量被声明为final后,只能被赋值一次,即它们的值在初始化后就不能再更改。这有助于确保数据的不变性,这对于创建不可变对象非常有用。
    final int MAX_VALUE = 100; // 定义一个常量,其值不能被修改
    int count = 0;
    count = MAX_VALUE; // 正确赋值
    // count = 200; // 错误赋值,会编译报错
  4. 修饰局部变量:局部变量被声明为final后,也必须在声明时或构造函数内赋值,之后不能再更改。这有助于提高代码的可读性和可维护性,因为它明确表明了变量的值在初始化后不会发生变化。
    public void myMethod() {final int localVar = 10; // 局部变量被声明为final// localVar = 20; // 错误,无法修改final变量的值
    }
  5. 修饰方法参数:当方法参数被声明为final时,它可以确保参数在方法执行期间不会被修改。这有助于避免在方法内部意外修改参数值的错误。
    public void myMethod(final int value) {// value = 20; // 错误,无法修改final参数的值
    }

final关键字是Java中一个重要的工具,它通过限制类的继承、方法的重写和变量的修改,帮助开发者编写更安全、更稳定的代码。在使用final关键字时,需要根据具体的需求和设计考虑来决定是否使用,以及如何使用,以确保代码的可读性和可维护性。

权限修饰符 

在Java中,权限修饰符是用来控制类、变量、方法和构造函数访问权限的一种机制。它们定义了其他类对这些成员的访问级别。Java提供了以下几种权限修饰符:

  1. public:公共的,没有访问限制。任何外部类都可以访问公共的成员。
    public class MyClass {public int publicVar; // 公共变量,可以在任何地方访问
    }class AnotherClass {MyClass obj = new MyClass();obj.publicVar = 10; // 可以访问公共变量
    }
  2. private:私有的,只能在其定义的类内部访问。从外部类无法直接访问私有成员,但可以通过公共方法(如getter和setter)进行访问。
    public class MyClass {private int privateVar; // 私有变量,只能在类内部访问public void setPrivateVar(int value) {privateVar = value; // 通过公共方法设置私有变量的值}public int getPrivateVar() {return privateVar; // 通过公共方法获取私有变量的值}
    }class AnotherClass {MyClass obj = new MyClass();// obj.privateVar = 10; // 错误,无法直接访问私有变量obj.setPrivateVar(10); // 通过公共方法设置私有变量的值int value = obj.getPrivateVar(); // 通过公共方法获取私有变量的值
    }
  3. protected:受保护的,可以在同一个包内以及子类中访问。如果试图从其他包的非子类中访问,则会出错。
    public class MyClass {protected int protectedVar; // 受保护的变量,可以在同一个包内以及子类中访问
    }class AnotherClass {MyClass obj = new MyClass();obj.protectedVar = 10; // 可以访问受保护变量(在同一个包内)
    }class SubClass extends MyClass {void accessProtectedVar() {protectedVar = 20; // 可以访问受保护变量(在子类中)}
    }
  4. 默认(无修饰符):也称为包级私有,只能在同一个包内访问。如果试图从其他包中访问,则会出错。
    package com.example;public class MyClass {int defaultVar; // 默认访问权限的变量,只能在同一个包内访问
    }class AnotherClass {MyClass obj = new MyClass();obj.defaultVar = 10; // 可以访问默认访问权限的变量(在同一个包内)
    }

这些修饰符可以用来控制对类、变量、方法和构造函数的访问,从而确保数据的安全性和封装性。在编写Java代码时,应根据具体需求选择适当的权限修饰符来保护成员的访问权限。

publicprotected默认private
同一类中
同一包中的类
不同包的子类
不同包中的无关类

静态代码块 

静态代码块是指在Java类中定义的静态代码块,它在类被加载时执行一次。静态代码块通常用于初始化静态变量或执行一些只需要执行一次的操作。以下是一个简单的Java静态代码块示例:

public class MyClass {static {System.out.println("This is a static block.");}public static void main(String[] args) {System.out.println("Hello, World!");}
}

在这个示例中,当MyClass类被加载时,静态代码块会被执行一次,输出"This is a static block."。然后,程序进入main方法,输出"Hello, World!"。

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

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

相关文章

C++从入门到精通——命名空间

命名空间 前言一、命名空间引例什么是命名空间 二、命名空间定义正常的命名空间定义嵌套的命名空间多个相同名称的命名空间 三、命名空间使用加命名空间名称及作用域限定符使用using将命名空间中某个成员引入使用using namespace 命名空间名称引用引用命名空间和引用头文件有什…

Unity PS5开发 天坑篇 之 URP管线与HDRP管线部署流程以及出包介绍04

目录 一, URP管线、HDRP管线下的Unity项目部署 1. PS5开发论坛关于Unity可支持的版本说明: 2. URP管线下的项目与部署 2.1 Build PS5 URP Project 2.2 运行画面 3. HDRP管线下的项目与部署 3.1 附上可以运行的画面: 4. PS5打包方式介绍 4.1 PC串流调试模式: Build Typ…

安装mysql8.0.36遇到的问题没有developer default 选项问题

安装mysql8.0.36的话没有developer default选项,直接选择customer就好了,点击next之后通过点击左边Available Products里面的号和中间一列的右箭头添加要安装的产品,最后会剩下6个 安装完成后默认是启动了,并且在电脑注册表注册了…

【Leetcode】单链表常见题

🔥个人主页:Quitecoder 🔥专栏:Leetcode刷题 本节内容我们来讲解常见的几道单链表的题型,文末会赋上单链表增删查,初始化等代码 目录 1.移除链表元素2.链表的中间节点3.返回倒数第K个节点:4.环…

华为云使用指南02

5.​​使用GitLab进行团队及项目管理​​ GitLab旨在帮助团队进行项目开发协作,为软件开发和运营生命周期提供了一个完整的DevOps方案。GitLab功能包括:项目源码的管理、计划、创建、验证、集成、发布、配置、监视和保护应用程序等。该镜像基于CentOS操…

【TB作品】MSP430G2553,超声波倒车雷达PCB,单片机,超声波SR04,键盘,oled,

题目 硬件:MSP430G2553、 SR04超声波传感器 、3*4键盘、 无源蜂鸣器、oled显示屏 软件 1 、实时显示测量得到的距离 2、按键设置一个报警门限数值,直接输入数值后确认 3、低于报警门限数值就开始报警,而且距离越近蜂鸣器的鸣叫频率越高 程序…

【踩坑】使用CenterNet训练自己的数据时的环境配置与踩坑

环境配置 系统:Ubuntu22.04 Python:3.8 CUDA:11.7 pytorch:2.2.1 因为种种原因没有使用原工程的老版本python和pytorch……但总之也跑通了,可喜可贺,可喜可贺。 新建conda环境: conda create -…

JavaEE之网络初识(网络中的一些基本概念)详解

😽博主CSDN主页: 小源_😽 🖋️个人专栏: JavaEE 😀努力追逐大佬们的步伐~ 目录 1. 前言 2. 网络中的一些基本概念 2.1 IP地址 2.2 端口号 2.3 网络协议 2.4 协议分层 2.5 封装 2.6 分用 (封装的逆向过程) 2.7 客户端 vs …

JUC并发编程之常用方法

sleep() public void testSleepAndYield() {Thread t1 new Thread(() -> {try {log.debug("t1-sleep...");Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}}, "t1");log.debug("t1 start 前的状态&#…

Appium设备交互API

设备交互API指的是操作设备系统中的一些固有功能,而非被测程序的功能,例如模拟来电,模拟发送短信,设置网络,切换横竖屏,APP操作,打开通知栏,录屏等。 模拟来电 make_gsm_call(phon…

Douyin视频详情数据API接口(视频详情,评论)

抖音官方并没有直接提供公开的视频详情数据采集API接口给普通用户或第三方开发者。抖音的数据采集通常受到严格的限制,以保护用户隐私和平台安全。 请求示例,API接口接入Anzexi58 如果您需要获取抖音视频详情数据,包括评论、点赞等&#xff…

软考 - 系统架构设计师 - 关系模型的完整性规则

前言 关系模型的完整性规则是一组用于确保关系数据库中数据的完整性和一致性的规则。这些规则定义了在关系数据库中如何存储、更新和查询数据,以保证数据的准确性和一致性。 详情 关系模型的完整性规则主要包括以下三类: 实体完整性规则 这是确保每个…

C++基本语法

C是如何工作的 文章目录 C是如何工作的1、新建Hello World工程1.1使用Visual Studio新建项目1.2 HelloWorld1.2.1 命名空间1.2.2 输出输出 1.3 注释1.4 函数1.4.1 使用有返回的函数1.4.2 自定义函数 1、新建Hello World工程 1.1使用Visual Studio新建项目 按照下面的图片&…

x86的内存分段机制

8086 是 Intel 公司第一款 16 位处理器,诞生于 1978 年,所以说它很古老。 一.8086 的通用寄存器 8086 处理器内部共有 8 个 16 位的通用处理器,分别被命名为 AX、 BX、 CX、 DX、 SI、 DI、 BP、 SP。如下图所示。 “通用”的意思是…

利用python搭建临时文件传输服务

场景 如果想从一台服务器上传输文件又多种方法,其中常见的是利用scp进行传输,但是需要知道服务器的账号密码才能进行传输,但有时候我们并不知道账号密码,这个时候我们就可以通过python -m SimpleHTTPServer 命令进行传输文件 启…

C语言例4-14:从键盘输入小写字母转换成大写字母并输出。

代码如下&#xff1a; //从键盘输入小写字母转换成大写字母并输出。 #include<stdio.h> int main(void) {char c1,c2;printf("输入小写字母&#xff1a; \n");c1 getchar(); //从键盘输入一个字符putchar(c1);printf(",%d\n",c1);c2 c1-32; …

Git基础(23):Git分支合并实战保姆式流程

文章目录 前言准备正常分支合并1. 创建两个不冲突分支2. 将dev合并到test 冲突分支合并1. 制造分支冲突2. 冲突合并 前言 Git分支合并操作 准备 这里先在Gitee创建了一个空仓库&#xff0c;方便远程查看内容。 正常分支合并 1. 创建两个不冲突分支 &#xff08;1&#xf…

C++ 控制语句(二)

一 break continue和goto语句 1 break语句 在switch语句中&#xff0c;分隔case子句&#xff0c;跳出switch语句。 在循环语句中可以立即终止循环语句的执行。 2 continue语句 功能:在一次循环过程中,跳过continue语句以下的语句,直 接进入下一次循环操作。 3 goto语句 …

Linux文件系统和日志管理

文件系统的组成 Linux 文件系统会为每个文件分配两个数据结构&#xff1a;索引节点&#xff08;index node&#xff09; 和 目录项&#xff08;directory entry&#xff09;&#xff0c;它们主要用来记录文件的元信息和目录层次结构。 索引节点&#xff0c;也就是 inode&#…

【数据结构】顺序表的实现——静态分配

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;数据结构 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…