Java | 包和内部类

news2024/11/18 9:36:20

目录

一、Java类包

1.1 类名冲突

1.2 完整的类路径

1.3 创建包

1.4 导入包

1.4.1 使用import关键字导入包

1.4.2 使用import导入静态成员

二、内部类

2.1 成员内部类

2.1.1 成员内部类简介

2.1.2 使用this关键字获取内部类与外部类的引用

2.2 匿名内部类


类除了具有普通的特性,还具有一些高级特性,如包、内部类等。包在整个管理过程中起到了非常重要的作用,使用包可以有效地管理繁杂的类文件解决类重名的问题。在类中应用包与权限修饰符,可以控制其他人对类成员的访问。Java中还有一个更为有效的隐藏实现细节的方式,那就是使用内部类,通过后可以向上转型为被内部类实现的公共接口。由于在类中可以定义多个内部类,实现接口的方式也不止一个,因此只要将内部类中的方法设置为类最小范围的修饰权限,即可将内部类的实现细节有效地隐藏。

一、Java类包

Java中提供了一种管理类文件的机制,就是类包。

1.1 类名冲突

编译器不会允许存在同名的类文件。解决这类问题的办法就是将这两个类放置在不同的类包中。

1.2 完整的类路径

编写Java程序经常用到String类,其实String类并不是它的完整名称。String的完整名称是:java.lang.String。一个完整的类名需要包名与类名的组合,每个类都隶属于一个类包,只要保证同一类包中的类不同名,就可以有效地避免同名类冲突的情况。

例如,一个程序中同时使用到java.util.Date类与java.sql.Date类,如果在程序中不指定完整的类路径,编译器不会知道这段代码使用的是java.util类包中的Date类还是java.sql类包中的Date类,所以需要在指定代码中给出完整的类路径。

例如,在程序中使用两个不同Date类的完整类路径,可以使用如下代码:

java.util.Date date=new java.util.Date();
java.sql.Date date2=new java.sql.Date(1000);

在Java中采用类包机制非常重要,类包不仅可以解决类名冲突问题,还可以在开发庞大的应用程序时,帮助开发人员管理庞大的应用程序组件,方便软件复用。

同一包中的类相互访问时,可以不指定包名。

1.3 创建包

在Java中包名设计应与文件系统结构相对应,如一个包名为com.mr,那么包中的类位于com文件夹下的mr子文件夹下。没有定义包的类会被归纳在默认包(default package)中。

定义包的语法如下:

package 包名

在类中指定包名时,需要将package表达式放置在程序的第一行,它必须是文件中的第一行非注释代码。使用package关键字为类指定包名之后,包名将会成为类名中的一部分,预示着这个类必须指定全名。例如,在使用位于com.mr包下的Dog.java类时,需要使用形如com.mr.Dog这样的表达式。

为了避免产生包名冲突现象,在Java中定义包名时通常使用创建者的Internet域名的反序,由于Internet域名是独一无二的,包名自然不会发生冲突。

package haha;          //指定包名
public class Math{
	public static void main(String[] args) {
		System.out.println("不是java.lang.Math类,而是com.mr.Math类");
	}
}

可以看出,在不同包中定义相同类名也是没有问题的。

1.4 导入包

1.4.1 使用import关键字导入包

如果某个类中需要使用Math类,可以使用Java中的import关键字指定是java.lang.Math类还是com.mr.Math类。例如,如果在程序中使用import关键字导入com.mr.Math类,在程序中使用Math类时会自动选择com.mr.Math类。

import com.mr.*           //导入com.mr包中的所有类
import com.mr.Math        //导入com.mr包中的Math类

如果类定义中已经导入com.mr.Math类,在类体中再使用其他包中的Math类时就必须指定完整的带有包格式的类名。例如,在上述情况下再使用java.lang包的Math类时就要使用全名格式java.lang.Math。

在程序中添加import关键字时,就开始在CLASSPATH指定的目录下进行查找,查找子目录com.mr,然后从这个目录下编译完成的文件中查找是否有名称符合者,最后寻找到Math.class文件。另外,当使用import指定了一个包中的所有类时,并不会指定这个包的子包中的类,如果用到这个包的子包中的类,需要再次对子包进行单独引用。

1.4.2 使用import导入静态成员

import关键字除了导入包外,还可以导入静态成员。使用import导入静态成员的语法如下:

import static 静态成员
package haha;          
import static java.lang.Math.max;         //导入静态成员方法
import static java.lang.System.out;       //导入静态成员变量
public class ImportTest{
	public static void main(String[] args) {
		out.println("1和4的较大值为:"+max(1,4));  //主方法中可以直接使用这些静态成员
	}
}

二、内部类

如果在类中再定义一个类,则将在类中再定义的那个类称为内部类。成员内部类和匿名类是最常见的内部类。

2.1 成员内部类

2.1.1 成员内部类简介

在一个类中使用内部类,可以在内部类中直接存取其所在类的私有成员变量。成员内部类的语法如下:

class OuterClass{      //外部类
    class InnerClass{  //内部类

    }
}

在成员内部类中可以随意使用外部类的成员方法及成员变量,尽管这些类成员被修饰为private。

内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。内部类初始化方式与其他类的初始化方式相同,都是使用new关键字。

例:使用内部成员类模拟发动机点火

首先创建Car类,Car类中有私有属性brand和start()方法,然后在Car类的内部创建Engine类,Engine类中有私有属性model和ignite()方法,最后打印出“启动大众朗行,发动机EA211点火”。

package haha;          
public class Car{               //创建汽车类
	private String brand;       //汽车品牌
	public Car(String brand) {  //汽车类的构造方法,参数为汽车品牌
		this.brand=brand;       //给汽车品牌赋值
	}
	class Engine{               //发动机类(内部类)
		String model;           //发动机型号
		public Engine(String model) {  //发动机类的构造方法,参数为发动机型号
			this.model=model;          //给发动机型号赋值
		}
		public void ignite() {         //(发动机)点火方法
			System.out.println("发动机"+this.model+"点火");
		}
	}
	public void start() {                //启动(汽车)方法
		System.out.println("启动"+this.brand);
	}
	public static void main(String[] args) {
		Car car=new Car("大众朗行");              //创建汽车类对象,并为汽车品牌赋值
		car.start();                           //汽车类对象调用启动(汽车)方法
		//创建发动机类(内部类)对象,并未发动机型号赋值
		Car.Engine engine=car.new Engine("EA211");
		engine.ignite();                       //发动机类对象调用(发动机)点火方法
	}
}

成员内部类不止可以在外部类中使用,在其它类中也可以使用。在其它类中创建内部类对象的语法如下:

外部类 outer = new 外部类();
外部类.内部类 inner = outer.new 内部类();

内部类对象会依赖于外部类对象,除非已经存在一个外部类对象,否则类中不会出现内部类对象。

2.1.2 使用this关键字获取内部类与外部类的引用

如果在外部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字。

例:在内部类中调用外部类对象

在项目中创建TheSameName类,在类中定义成员变量x,再定义一个内部类Inner,在内部类中也创建x变量,并在内部类的doit()方法中定义一个局部变量x。

package haha;          
public class TheSameName{
	private int x=7;              //外部类的x
	private class Inner{
		private int x=9;          //内部类的x
		public void doit() {
			int x=11;             //局部变量x
			x++;
			this.x++;             //调用内部类的x
			TheSameName.this.x++; //调用外部类的x
		}
	}
}

2.2 匿名内部类

匿名类是只在创建对象时才会编写类体的一种写法。匿名类的特点是“现用现写”,其语法如下:

new 父类/父接口(){
    子类实现的内容
};

最后一个大括号之后有分号。

例:使用匿名内部类创建一个抽象狗类的对象

创建一个抽象的狗类,类中有一个颜色属性和两个抽象方法,在测试类的主方法中创建抽象类对象,并用匿名内部类实现该对象的抽象方法。

package haha;  

abstract class Dog{
	String Color;
	public abstract void move();
	public abstract void call();
}

public class Demo{
	public static void main(String args[]) {
		Dog maomao=new Dog() {
			public void move() {
				System.out.println("四腿狂奔");
			}
			public void call() {
				System.out.println("嗷呜~");
			}
		};
		maomao.Color="灰色";
		maomao.move();
		maomao.call();
	}
}

在程序中maomao只能解读为“一只具体的无名之狗”。

使用匿名类时应该遵循以下原则:

  • 匿名类不能写构造方法。
  • 匿名类不能定义静态的成员。
  • 如果匿名类创建的对象没有赋值给任何引用变量,会导致该对象用完一次就会被Java虚拟机销毁。

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

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

相关文章

无涯教程-Perl - getnetbyname函数

描述 此函数返回由NAME指定的网络信息(在列表context中)($name,$aliases,$addrtype,$net) 语法 以下是此函数的简单语法- getnetbyname NAME返回值 此函数在错误时返回undef,否则在标量context中返回网络地址,在错误时返回空列表,否则在列表context中返回网络记录(名称,别…

在软件测试中,如何有效地跟踪和管理缺陷?

在软件测试中,跟踪和管理缺陷是非常重要的,因为这有助于确保所有问题得到妥善处理,避免在产品发布后出现问题。以下是跟踪和管理缺陷的一些有效方法: 1.创建缺陷报告:当发现一个缺陷时,应该立即创建一个缺…

前端进阶js02----null和undefined的区别

1.相同点 1)都是原始类型的值且保存在栈中。 2) 在布尔运算中都会被认为是false 2.不同点 1)null是js的关键字,表示空值;undefined不是关键字,是一个全局变量。 2)值相同,但类型不一样 值相同&#xff1a…

Day 25 C++ queue 容器(队列)

文章目录 queue 基本概念定义注意基本概念队头(Front)——指向队列中最早添加的元素的位置。队尾(Rear)——指向队列中最后添加的元素的位置。入队(Enqueue)——将元素添加到队尾。出队(Dequeue…

Docker 方式 部署 vue 项目 (docker + vue + nginx)

1.安装好 nginx 。 2. 把 vue 项目的源码克隆到确定目录下。用 git 管理,所以直接 git clone 到既定目录就行了。 如我的目录是:/root/jiangyu/projects/gentle_vue/gentle_vue_code 。 3. 项目打包: npm run build 复制 会自动生成 dist…

【Linux】-进程概念之进程优先级(如何去进行调度以及进程切换),还不进来看看??

💖作者:小树苗渴望变成参天大树🎈 🎉作者宣言:认真写好每一篇博客💤 🎊作者gitee:gitee✨ 💞作者专栏:C语言,数据结构初阶,Linux,C 动态规划算法🎄 如 果 你 …

小小推磨台(我在芜湖等你)

君问归期已有期,江城相逢话恩奇 我 渐渐明了 因为 有祂同行 有期待 有不知所措 离别故乡 去远方 是求学 更是认识祂 我 还不知 那里有没有家 或许有 或许有人找寻 忽然间 想到不认识的相逢 已然在祂预备之中 在那里 侧耳倾听 彼此谈论 那是和睦同居 好的无比 if (&q…

优雅地处理RabbitMQ中的消息丢失

目录 一、异常处理 二、消息重试机制 三、错误日志记录 四、死信队列 五、监控与告警 优雅地处理RabbitMQ中的消息丢失对于构建可靠的消息系统至关重要。下面将介绍一些优雅处理消息丢失的方案,包括异常处理、重试机制、错误日志记录、死信队列和监控告警等。…

科技资讯|苹果手机版Vision Pro头显专利曝光,内嵌苹果手机使用

根据美国商标和专利局(USPTO)公示的清单,苹果公司近日获得了一项头显相关的技术专利,展示了一款亲民款 Vision Pro 头显,可以将 iPhone 放置在头显内部充当屏幕。 根据patentlyapple 媒体报道,这是苹果公司…

设计模式——单例模式(懒汉和饿汉)

单例模式 一、概念 单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。一个类只能有一个实例在生活中是很常见的,比如打印机程…

若依管理系统后端将 Mybatis 升级为 Mybatis-Plus

文章目录 说明流程增加依赖修改配置文件注释掉MybatisConfig里面的Bean 代码生成使用IDEA生成代码注意 Controller文件 说明 若依管理系统是一个非常完善的管理系统模板,里面含有代码生成的方法,可以帮助用户快速进行开发,但是项目使用的是m…

单例模式_饿汉模式_懒汉模式(含线程安全写法)

前言 某个类在程序中只存在唯一一份实例,叫做单例模式。 目录 前言 一、饿汉模式 二、懒汉模式 (一)单线程写法 (二)线程安全写法 (三)线程安全和不安全写法的区别 结语 一、饿汉模式 …

分享windwosServer2012R--ISO镜像下载地址(含激活教程)

windowsServer2012R----急速网盘下载地址:点击下载 提取码:888999 激活下载:点击下载 提取码:888999

AI和GPT的崛起,对未来项目管理的影响与变革︱原微软项目经理陆敏

原微软项目经理和产品经理人才顾问陆敏先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾,演讲议题:AI和GPT的崛起,对未来项目管理的影响与变革。大会将于8月12-13日在北京举办,敬请关注! 议题简要&#xff1…

从LeakCanary看Service生命周期监控

作者:小海编码日记 大家都知道使用LeakCanary可以监控项目中存在的 内存泄漏 问题,那么LeakCanary是怎么实现的呢?LeakCanary通过检测程序中对象的引用关系,收集应该被回收的对象并标记,随后等待GC后,检查该…

线上电影票票务系统开发--APP、H5小程序、网站

一、系统架构 后端架构:采用微服务架构,包括API接口、业务逻辑层和数据访问层。使用云服务器进行数据存储,保证数据的安全性和稳定性。 前端架构:APP采用原生开发方式,前端与后端通过API接口进行数据交互。 二、功能…

司空见惯 - Realwear公司及产品介绍

基于安卓系统的头显设备,Android based headset display,集成了摄像头,还有个小显示屏。 设备价格很贵哦: 显示屏在前方: 官方网站:https://www.realwear.com/ RealWear head-mounted displays. Built to …

直播平台的秘密武器:揭秘流行直播实时美颜SDK的背后技术

近年来,随着社交媒体和直播平台的崛起,实时美颜成为了许多用户在分享自己生活的过程中的一项重要需求。无论是个人的自拍照片,还是主播在直播中的形象展示,美颜效果都直接影响着观众的视觉感受。而支撑这种实时美颜效果背后的技术…

uniapp 实现滑动视图切换 顶部滚动导航栏

无论小程序的时候一般有这个功能,在页面处于首页时候,滑动视图,切换视图顶部滚动导航也跟着切换 1.想要实现这个功能就需要实现顶部导航栏,首先实现顶部滚导航栏 点击高亮颜色显示 模板代码 <scroll-view scroll-x"true" class"scroll-content" > …

MySQL不知道密码,直接修改密码

很简单&#xff0c;我们跳过验证&#xff0c;直接进去修改就好 修改配置文件 vim /etc/my.cnf在[mysqld]下直接添加配置 skip-grant-tables如图&#xff1a; 保存&#xff0c;退出即可。 重启服务 service mysqld restart进入MySQL #(直接点击回车&#xff0c;密码为空)…