爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      面向对象编程(下)

      首页 知识中心 软件开发 文章详情页

      面向对象编程(下)

      2023-07-26 08:03:07 阅读次数:427

      java,接口,方法

      1、关键字:static

      当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。

      说明:

      class Circle{
      	private double radius;
      	public Circle(double radius){this.radius=radius;}
      	public double findArea(){return Math.PI*radius*radius;
      	}
      }
      

      创建两个Circle对象

      Circle c1=new Circle(2.0); //c1.radius=2.0
      Circle c2=new Circle(3.0); //c2.radius=3.0
      

      Circle类中的变量radius是一个实例变量(instance variable),它属于类的每一个对象,不能被同一个类的不同对象所共享。

      上例中c1的radius独立于c2的radius,存储在不同的空间。c1中的radius变化不会影响c2的radius,反之亦然。

      如果想让一个类的所有实例共享数据,就用类变量!

      类属性、类方法的设计思想
       类属性作为该类各个对象之间共享的变量。在设计类时,分析哪些属性不因对象的不同而改变,将这些属性设置为类属性。相应的方法设置为类方法。
       如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。

      使用范围:

      • 在Java类中,可用static修饰属性、方法、代码块、内部类

      被修饰后的成员具备以下特点:

      • 随着类的加载而加载
      • 优先于对象存在
      • 修饰的成员,被所有对象所共享
      • 访问权限允许时,可不创建对象,直接被类调用

      类变量(class Variable)
      类变量(类属性)由该类的所有实例共享

      public class Person {
      	private int id;
      	public static int total = 0;//静态变量
      	public Person() {
      	total++;
      	id = total;
      	}
      }
      

      面向对象编程(下)
      类变量应用举例

      class Person { 
      	private int id;
      	public static int total = 0;
      	public Person() {
      		total++;
      		id = total;
      	}
      	public static void main(String args[]){
      		Person Tom=new Person();
      		Tom.id=0;
      		total=100; // 不用创建对象就可以访问静态成员
      	}
      }
      
      public class StaticDemo {
      	public static void main(String args[]) {
      		Person.total = 100; // 不用创建对象就可以访问静态成员
      		//访问方式:类名.类属性,类名.类方法
      		System.out.println(Person.total);
      		Person c = new Person();
      		System.out.println(c.total); //输出101
      	}
      }
      

      类变量 vs 实例变量内存解析
      面向对象编程(下)

      静态变量的内存解析
      面向对象编程(下)

      类方法(class method)
      没有对象的实例时,可以用类名.方法名()的形式访问由static修饰的类方法。
      在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。

      class Person {
      	private int id;
      	private static int total = 0;
      	public static int getTotalPerson() { 
      		//id++; //非法
      		return total;
      	}
      	public Person() {
      		total++;
      		id = total;
      	}
      }
      
      public class PersonTest {
      	public static void main(String[] args) {
      		System.out.println("Number of total is " + Person.getTotalPerson());
      		//没有创建对象也可以访问静态方法
      		Person p1 = new Person();
      		System.out.println( "Number of total is "+ Person.getTotalPerson());
      	}
      }
      

      细节:

      因为不需要实例就可以访问static方法,因此static方法内部不能有this。(也不能有super ? YES!)
      static修饰的方法不能被重写

      class Person {
      	private int id;
      	private static int total = 0;
      	public static void setTotalPerson(int total){
      		this.total=total; //非法,在static方法中不能有this,也不能有super
      }
      	public Person() {
      		total++;
      		id = total;
      	}
      }
      
      public class PersonTest {
      	public static void main(String[] args) {
      		Person.setTotalPerson(3);
      	}
      }
      

      单例 (Singleton)设计模式
      设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模免去我们自己再思考和摸索。就像是经典的棋谱,不同的棋局,我们用不同的棋谱。”套路”

      所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。

      饿汉式

      class Singleton {
      	// 1.私有化构造器
      	private Singleton() {
      	}
      	// 2.内部提供一个当前类的实例
      	// 4.此实例也必须静态化
      	private static Singleton single = new Singleton();
      	// 3.提供公共的静态的方法,返回当前类的对象
      	public static Singleton getInstance() {
      		return single;
      	}
      }
      
      

      懒汉式

      class Singleton {
      	// 1.私有化构造器
      	private Singleton() {
      }
      	// 2.内部提供一个当前类的实例
      	// 4.此实例也必须静态化
      	private static Singleton single;
      	// 3.提供公共的静态的方法,返回当前类的对象
      	public static Singleton getInstance() {
      		if(single == null) {
      			single = new Singleton();
      	}
      		return single;
      	}
      }
      

      懒汉式暂时还存在线程安全问题

      单例模式的优点:
      由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。

      应用场景

      • 网站的计数器,一般也是单例模式实现,否则难以同步。
      • 应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
      • 项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,都生成一个对象去读取。
      • Application 也是单例的典型应用
        • Windows的**Task Manager (任务管理器)**就是很典型的单例模式
        • Windows的**Recycle Bin (回收站)**也是典型的单例应用。在整个系统运行过程
          中,回收站一直维护着仅有的一个实例。

      2、理解main方法的语法

      由于Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又因为Java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static的,该方法接收一个String类型的数组参数,该数组中保存执行Java命令时传递给所运行的类的参数。

      又因为main() 方法是静态的,我们不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员,这种情况,我们在之前的例子中多次碰到。
      命令行参数用法举例

      public class CommandPara {
      	public static void main(String[] args) {
      		for (int i = 0; i < args.length; i++) {
      		System.out.println("args[" + i + "] = " + args[i]);
      		}
      	}
      }
      

      //运行程序CommandPara.java
      java CommandPara “Tom" “Jerry" “Shkstart"
      面向对象编程(下)

      输出结果:
      args[0] = Tom
      args[1] = Jerry
      args[2] = Shkstart

      3、代码块

      代码块(或初始化块)的作用:

      • 对Java类或对象进行初始化

      代码块(或初始化块)的分类:

      • 一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块
        (static block),没有使用static修饰的,为非静态代码块。

      static代码块通常用于初始化static的属性

      class Person {
      	public static int total;
      	static {
      		total = 100;//为total赋初值
      	}
      	…… //其它属性或方法声明
      }
      

      静态代码块:用static 修饰的代码块

      1. 可以有输出语句。
      2. 可以对类的属性、类的声明进行初始化操作。
      3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
      4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
      5. 静态代码块的执行要先于非静态代码块。
      6. 静态代码块随着类的加载而加载,且只执行一次。

      非静态代码块:没有static修饰的代码
      7. 可以有输出语句。
      8. 可以对类的属性、类的声明进行初始化操作。
      9. 除了调用非静态的结构外,还可以调用静态的变量或方法。
      10. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
      11. 每次创建对象的时候,都会执行一次。且先于构造器执行。

      总结:程序中成员变量赋值的执行顺序
      面向对象编程(下)

      4、关键字:final

      在Java中声明类、变量和方法时,可使用关键字final来修饰,表示“最终的”。

      • final标记的类不能被继承。提高安全性,提高程序的可读性。
        • String类、System类、StringBuffer类
      • final标记的方法不能被子类重写。
        • 比如:Object类中的getClass()。
      • final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只能被赋值一次。
        • final标记的成员变量必须在声明时或在每个构造器中或代码块中显式赋值,然后才能使用。
        • final double MY_PI = 3.14;

      1. final修饰类

      final class A{
      }
      class B extends A{ //错误,不能被继承。
      }
      

      2. final修饰方法

      class A {
      	public final void print() {
      		System.out.println("A");
      	}
      }
      class B extends A {
      	public void print() { // 错误,不能被重写。
      		System.out.println("尚硅谷");
      	}
      }
      

      3. final修饰变量——常量

      class A {
      	private final String INFO = "atguigu"; //声明常量
      	public void print() {
      		//The final field A.INFO cannot be assigned
      		//INFO = "尚硅谷";
      	}
      }
      

      关键字final应用举例

      public final class Test {
      	public static int totalNumber = 5;
      	public final int ID;
      	public Test() {
      		ID = ++totalNumber; // 可在构造器中给final修饰的“变量”赋值
      }
      public static void main(String[] args) {
      	Test t = new Test();
      	System.out.println(t.ID);
      	final int I = 10;
      	final int J;
      	J = 20;
      	J = 30; // 非法
      	}
      }
      

      5、抽象类与抽象方法

      随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

      特点:

      • 用abstract关键字来修饰一个类,这个类叫做抽象类。
      • 用abstract来修饰一个方法,该方法叫做抽象方法。
        • 抽象方法:只有方法的声明,没有方法的实现。以分号结束:
        • 比如:public abstract void talk();
      • 含有抽象方法的类必须被声明为抽象类。
      • 抽象类不能被实例化。抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。
      • 不能用abstract修饰变量、代码块、构造器;
      • 不能用abstract修饰私有方法、静态方法、final的方法、final的类。

      抽象类举例

      abstract class void A {
      	m1(); 抽象类举例
      	public void m2() {
      	System.out.println("A类中定义的m2方法");
      	}
      }
      class B extends A {
      	void m1() {
      	System.out.println("B类中定义的m1方法");
      	}
      }
      public class Test {
      	public static void main(String args[]) {
      	A a = new B();
      	a.m1();
      	a.m2();
      	}
      }
      

      抽象类应用
      抽象类是用来模型化那些父类无法确定全部实现,而是由其子类提供具体实现的对象的类。

      Java允许类设计者指定:超类声明一个方法但不提供实现,该方法的实现由子类提供。
      这样的方法称为抽象方法。有一个或更多抽象方法的类称为抽象类。

      思 考?
      为什么抽象类不可以使用final关键字声明?

      • 抽象类就是要被继承的,不能用final声明,final声明的类不可继承;

      一个抽象类中可以定义构造器吗?

      • 抽象类可以定义构造方法

      既然抽象类并不能实例化,那抽象类中的构造函数存在的意义是什么?

      • 抽象类必须被子类继承来实现。
      • 子类在调用父类时 无论自己有没有构造方法都会先去执行父类无参的函数。哪怕父类是抽象类。虽然抽象类不能被实例化,但是可以在构造方法中初始化一些参数;也可以在子类中调用父类的构造方法。

      多态的应用:模板方法设计模式(TemplateMethod)
      抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

      解决的问题:
      当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
      换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。

      abstract class Template {
      	public final void getTime() {
      		long start = System.currentTimeMillis();
      		code();
      		long end = System.currentTimeMillis();
      		System.out.println("执行时间是:" + (end - start));
      	}
      	public abstract void code();
      }
      class SubTemplate extends Template {
      	public void code() {
      		for (int i = 0; i < 10000; i++) {
      			System.out.println(i);
      		}
      	}
      }
      

      6、 接口(interface)

      概述

      • 一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。
      • 另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接。
      • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要…则必须能…”的思想。**继承是一个"是不是"的关系,而接口实现则是 "能不能"**的关系。
      • 接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。

      接口(interface)是抽象方法和常量值定义的集合。

      接口的特点:
      1. 用interface来定义。
      2. 接口中的所有成员变量都默认是由public static final修饰的。
      3. 接口中的所有抽象方法都默认是由public abstract修饰的。
      4. 接口中没有构造器。
      5. 接口采用多继承机制。

      接口定义的举例:

      public interface Runner {
      	int ID = 1; //public static final int ID = 1;
      	void start(); //public abstract void start()
      	public void run();//public abstract void run();
      	void stop();//public abstract void stop();
      }
      

      定义Java类的语法格式:先写extends,后写implements

      • class SubClass extends SuperClass implements InterfaceA{ }

      一个类可以实现多个接口,接口也可以继承其它接口。
      实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。
      接口的主要用途就是被实现类实现。(面向接口编程)
      与继承关系类似,接口与实现类之间存在多态性
      接口和类是并列关系,或者可以理解为一种特殊的类。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义(JDK7.0及之前),而没有变量和方法的实现。

      一个类可以实现多个无关的接口

      interface Runner { public void run();}
      interface Swimmer {public double swim();}
      class Creator{public int eat(){…}} 
      class Man extends Creator implements Runner ,Swimmer{
      	public void run() {……}
      	public double swim() {……}
      	public int eat() {……}
      }
      

      与继承关系类似,接口与实现类之间存在多态性

      public class Test{
      	public static void main(String args[]){
      	Test t = new Test();
      	Man m = new Man();
      	t.m1(m);
      	t.m2(m);
      	t.m3(m);
      }
      	public String m1(Runner f) { f.run(); }
      	public void m2(Swimmer s) {s.swim();}
      	public void m3(Creator a) {a.eat();}
      }
      

      接口和抽象类之间的对比

      No. 区别点 抽象类 接口
      1 定义 包含抽象方法的类 主要是抽象方法和全局常量的集合
      2 组成 构造方法、抽象方法、普通方法、常量、变量 常量、抽象方法、(jdk8.0:默认方法、静态方法)
      3 使用 子类继承抽象类(extends) 子类实现接口(implements)
      4 关系 抽象类可以实现多个接口 接口不能继承抽象类,但允许继承多个接口
      5 常见设计模式 模板方法 简单工厂、工厂方法、代理模式
      6 对象 都通过对象的多态性产生实例化对象  
      7 局限 抽象类有单继承的局限 接口没有此局限
      8 实际 作为一个模板 是作为一个标准或是表示一种能力
      9 选择 如果抽象类和接口都可以使用的话,优先使用接口,因为避免单继承的局限  

      在开发中,常看到一个类不是去继承一个已经实现好的类,而是要么继承抽象类,
      要么实现接口。

      Java 8中关于接口的改进
      Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。

      静态方法:使用 static关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection/Collections或者Path/Paths这样成对的接口和类。

      默认方法:默认方法使用default关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。比如:java 8 API中对Collection、List、Comparator等接口提供了丰富的默认方法。

      举例:

      public interface AA {
      	double PI = 3.14;
      	public default void method() {
      		System.out.println("北京");
      	}
      	default String method1() {
      		return "上海";
      	}
      	public static void method2() {
      		System.out.println(“hello lambda!");
      	}
      }
      

      接口中的默认方法

      若一个接口中定义了一个默认方法,而另外一个接口中也定义了一个同名同参数的方法(不管此方法是否是默认方法),在实现类同时实现了这两个接口时,会出现:接口冲突。

      • 解决办法:实现类必须覆盖接口中同名同参数的方法,来解决冲突。

      若一个接口中定义了一个默认方法,而父类中也定义了一个同名同参数的非抽象方法,则不会出现冲突问题。因为此时遵守:类优先原则。接口中具有相同名称和参数的默认方法会被忽略。

      举例:

      	interface Filial {// 孝顺的
              default void help() {
                  System.out.println("老妈,我来救你了");
              }
          }
          interface Spoony {// 痴情的
              default void help() {
                  System.out.println("媳妇,别怕,我来了");
              }
          }
           class Man implements Filial, Spoony {
              @Override
              public void help() {
                  System.out.println("我该怎么办呢?");
                  Filial.super.help();
                  Spoony.super.help();
              }
          }
      

      7、内部类

      当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。

      在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。

      Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。

      • Inner class的名字不能与包含它的外部类类名相同;

      分类: 成员内部类(static成员内部类和非static成员内部类)
         局部内部类(不谈修饰符)、匿名内部类

      成员内部类作为类的成员的角色:

      • 和外部类不同,Inner class还可以声明为private或protected;
      • 可以调用外部类的结构
      • Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员 变量;

      成员内部类作为类的角色:

      • 可以在内部定义属性、方法、构造器等结构
      • 可以声明为abstract类 ,因此可以被其它的内部类继承
      • 可以声明为final的
      • 编译以后生成OuterClass$InnerClass.class字节码文件(也适用于局部内部类)

      【注意】

      1. 非static的成员内部类中的成员不能声明为static的,只有在外部类或static的成员
        内部类中才可声明static成员。
      2. 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
      3. 成员内部类可以直接使用外部类的所有成员,包括私有的数据
      4. 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的

      举例:

      class Outer {
      	private int s;
      	public class Inner {
      		public void mb() {
      		s = 100;
      		System.out.println("在内部类Inner中s=" + s);
      	}
      }
      public void ma() {
      	Inner i = new Inner();
      	i.mb();
      	}
      }
      public class InnerTest {
      	public static void main(String args[]) {
      		Outer o = new Outer();
      		o.ma();
      	}
      }
      
      public class Outer {
      	private int s = 111;
      	public class Inner {
      		private int s = 222;
      		public void mb(int s) {
      			System.out.println(s); // 局部变量s
      			System.out.println(this.s); // 内部类对象的属性s
      			System.out.println(Outer.this.s); // 外部类对象属性s
      	}
      }
      public static void main(String args[]) {
      	Outer a = new Outer();
      	Outer.Inner b = a.new Inner();
      	b.mb(333);
      	}
      }
      //333
      //222
      //111
      

      如何声明局部内部类
      面向对象编程(下)

      如何使用局部内部类

      • 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方
        都不能使用该类
      • 但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类
        的父类或父接口类型

      局部内部类的特点

      • 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号,以及数字编号。
      • 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。
      • 局部内部类可以使用外部类的成员,包括私有的。
      • 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。
      • 局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
      • 局部内部类不能使用static修饰,因此也不能包含静态成员

      匿名内部类
      概念:
      匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。

      格式:

      new 父类构造器(实参列表)|实现接口(){
      	//匿名内部类的类体部分
      }
      

      匿名内部类的特点
      1. 匿名内部类必须继承父类或实现接口
      2. 匿名内部类只能有一个对象
      3. 匿名内部类对象只能使用多态形式引用

      举例:

      public class Outer {
          public static void main(String[] args) {
      
              new Outer().callInner(new A() {
                  //接口是不能new但此处比较特殊是子类对象实现接口,只不过没有为对象取名
                  @Override
                  public void fun1() {
                      System.out.println("implement for fun1");
                  }
              });// 两步写成一步了
          }
      
          public void callInner(A a) {
              a.fun1();
          }
      } 
      
      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.csdn.net/qq_44732146/article/details/120257507,作者:胡八一,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:面向对象编程(中)

      下一篇:Java常用类

      相关文章

      2025-05-14 10:33:25

      超级好用的C++实用库之网络

      在网络相关的项目中,我们经常需要去获取和设置设备的IP地址、子网掩码、网关地址、MAC地址等信息。这些信息一般与操作系统相关,在Windows系统和Linux系统上调用的接口是不一样的。

      2025-05-14 10:33:25
      Linux , 参数 , 地址 , 接口 , 网卡 , 返回值
      2025-05-14 10:33:16

      30天拿下Rust之字符串

      在Rust中,字符串是一种非常重要的数据类型,用于处理文本数据。Rust的字符串是以UTF-8编码的字节序列,主要有两种类型:&str和String。其中,&str是一个对字符数据的不可变引用,更像是对现有字符串数据的“视图”,而String则是一个独立、可变更的字符串实体。

      2025-05-14 10:33:16
      amp , Rust , str , String , 使用 , 字符串 , 方法
      2025-05-14 10:33:16

      30天拿下Rust之向量

      在Rust语言中,向量(Vector)是一种动态数组类型,可以存储相同类型的元素,并且可以在运行时改变大小。向量是Rust标准库中的一部分,位于std::vec模块中。

      2025-05-14 10:33:16
      Rust , 使用 , 元素 , 向量 , 方法 , 索引 , 迭代
      2025-05-14 10:03:05

      30天拿下Rust之HashMap

      HashMap,被称为哈希表或散列表,是一种可以存储键值对的数据结构。它使用哈希函数将键映射到存储位置,以便可以快速检索和更新元素。

      2025-05-14 10:03:05
      HashMap , 使用 , 哈希 , 引用 , 方法 , 遍历 , 键值
      2025-05-14 10:02:58

      java休眠到指定时间怎么写

      java休眠到指定时间怎么写

      2025-05-14 10:02:58
      java , sleep , Thread , util , 方法
      2025-05-14 10:02:58

      30天拿下Rust之结构体

      在Rust语言中,结构体是一种用户自定义的数据类型,它允许你将多个相关的值组合成一个单一的类型。结构体是一种复合数据类型,可以用来封装多个不同类型的字段,这些字段可以是基本数据类型、其他结构体、枚举类型等。通过使用结构体,你可以创建更复杂的数据结构,并定义它们的行为。

      2025-05-14 10:02:58
      Rust , 使用 , 字段 , 实例 , 方法 , 示例 , 结构
      2025-05-14 10:02:58

      java项目多端数据同步解决方案

      多端数据同步是指在多个设备(例如桌面应用、移动应用、Web应用)之间保持数据的一致性。

      2025-05-14 10:02:58
      java , Spring , WebSocket , 同步 , 数据 , 版本号
      2025-05-14 10:02:48

      typescript 将数组清空

      在TypeScript或JavaScript开发中,数组是用于存储和管理一组数据的基础数据结构。当需要清空一个数组时,有多种方法可以实现,而选择合适的方法不仅影响代码的可读性,还会对性能产生一定的影响。不同场景下,选择适合的清空数组的方法至关重要。

      2025-05-14 10:02:48
      length , pop , 引用 , 数组 , 方法
      2025-05-14 09:51:21

      java 判断map为null或者空

      java 判断map为null或者空

      2025-05-14 09:51:21
      Java , Map , null , 方法 , 是否 , 检查 , 示例
      2025-05-14 09:51:15

      JAVA 两个类同时实现同一个接口

      在Java中,两个类同时实现同一个接口是非常常见的。接口定义了一组方法,实现接口的类必须提供这些方法的具体实现。

      2025-05-14 09:51:15
      Lambda , 函数 , 实现 , 接口 , 方法 , 表达式
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5235185

      查看更多

      最新文章

      超级好用的C++实用库之网络

      2025-05-14 10:33:25

      30天拿下Rust之向量

      2025-05-14 10:33:16

      java项目多端数据同步解决方案

      2025-05-14 10:02:58

      java 判断map为null或者空

      2025-05-14 09:51:21

      java怎么对线程池做监控

      2025-05-14 09:51:15

      JAVA 两个类同时实现同一个接口

      2025-05-14 09:51:15

      查看更多

      热门文章

      JAVA__接口的作用

      2023-04-18 14:14:13

      Java学习之算术运算符两只老虎

      2023-04-19 09:23:13

      排序算法Java版-归并排序算法

      2023-04-24 11:25:19

      JAVA多线程学习笔记

      2023-05-11 06:05:48

      什么是api接口

      2023-03-22 09:03:21

      try...catch...finally java

      2023-03-29 09:40:26

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      Java中的泛型编程详解

      合并排序-多线程算法

      解压特定zip压缩文件中特定文件,Java

      pytest源码目录概要分析

      【Java】Log4j远程命令执行漏洞修复最新版下载

      Java学习List集合存储学生对象并遍历

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号