Java基础之匿名内部类和Object类4月打卡day15

举报
java厂长 发表于 2022/04/13 09:06:10 2022/04/13
【摘要】 Java基础之匿名内部类和Object类4月打卡day15 关于作者作者介绍🍓 博客主页:作者主页🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。 1、匿名内部类内部类:在一个类的内部定义了另外的类,称为内部类,匿名内部类...

Java基础之匿名内部类和Object类4月打卡day15

关于作者

  • 作者介绍

🍓 博客主页:作者主页

🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。

🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。

1、匿名内部类

内部类:在一个类的内部定义了另外的类,称为内部类,匿名内部类指的是没有名字的内部类。为了清楚内部类的主要作用,下面首先观察一个代码。

interface IMessage{
	public void print();
}
class MessageImpl implements IMessage{//定义接口实现类
	public void print(){
		System.out.println("Hello World");
	}
}
class Demo{
	public static void get(IMessage msg){//接受接口对象
		msg.print();
	}
}
public class TestDemo1{
	public static void main(String args[]){
		IMessage msg = new MessageImpl();//子类为接口实例化
		Demo.get(msg);//传递msg对象
	}
}

如果说现在MessageImpl这个子类只使用一次,有必要按照以上的方式进行定义吗?

这个时候MessageImpl就没有什么意义了,但是可以利用匿名内部类的概念来解决此问题。匿名内部类是在抽象累和接口的基础之上发展起来的。

interface IMessage{
	public void print();
}
class Demo{
	public static void get(IMessage msg){//接受接口对象
		msg.print();
	}
}
public class TestDemo1{
	public static void main(String args[]){
		IMessage msg = new IMessage(){//匿名内部类
			public void print(){
				System.out.println("hello,world!");
			}
		};
		Demo.get(msg);//传递msg对象
	}
}

结论:基本上搞匿名内部类都应该在接口或抽象类形式上完成。

在抽象类中使用匿名内部类

abstract class Message{
	public void print(){
		System.out.print(this.getInfo());
	}
	public abstract String getInfo();
}
class Demo{
	public static void get(Message msg){//接受接口对象
		msg.print();
	}
}
public class TestDemo1{
	public static void main(String args[]){
		Demo.get(new Message(){
			public String getInfo(){
				return "www.baidu.com";
			}
		});//传递msg对象
	}
}

强调:一个普通类进行不要再去有子类进行继承,能够继承的只是抽象类和接口,所以在普通类上继续使用

匿名内部类的形式来定义子类,但是在正常的开发逻辑上是错误的。

2、Object类简介

在Java的定义之中,除了Object类之外,所有的类实际上都存在继承关系,即:如果现在定义了一个类,没有默认继承任何一个父类的话,则默认讲继承Object类,以下两种类最终定义效果是完全一样的。

Object类的无参构造是专门子类提供服务的。

方法名称 类型 描述
public String toString() 普通 取得对象信息
public boolean equals(Object obj) 普通 对象的比较
public int hashCode() 普通 返回对象的哈希码值
2.1 取得对象信息toString()

toString()的核心目的在于取得对象信息。相当于替换了getInfo()方法的功能。

class Person{
	private String name;
	private int age;
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	public String toString(){
		return "name = " + this.name + ",age = " + this.age ;
	}
}

public class TestDemo2{
	public static void main(String args[]){
		Person p = new Person("zsr",18);
		System.out.print(p.toString());
	}
}
2.2 对象的比较equals()

实际上对于equals()方法应该并不陌生,这个方法在String类中见过,String是Object类的子类,所以String类的equals()方法就是覆写了Object类中的equals()方法,在Object类之中,默认的equals()方法实现比较的是两个对象的内存地址数值,但是并不符合与真正的对象比较需要。对象比较之前也写过,但是之前那是自己定义的一个新的方法名称,今天可以给出标准的方法名称:equals()。

class Person{
	private String name;
	private int age;
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	public boolean equals(Object anObject){
		if(anObject == null){
			return false;
		}
		if(this == anObject){
			return true;
		}
		//判断anObject的实例是不是Person
		if( !(anObject instanceof Person)){
			return false;
		}
		//必须将Object类型变为Person类型后才可以调用name和age属性
		Person per = (Person) anObject;
		return this.name.equals(per.name) && this.age == per.age;
	}
	public String toString(){//覆写Object类方法
		return "name = " + this.name + ",age = " + this.age ;
	}
}

public class TestDemo3{
	public static void main(String args[]){
		Person per1 = new Person("zsr",18);
		Person per2 = new Person("zsr",18);
		//true
		System.out.println(per1.equals(per2));
		//false
		System.out.println(per1.equals("Hello,world!"));
	}
}

但是需要有一个注意,很多人在写对象的比较会使用如下的形式:

  • public boolean equals(Person anObject)

因为父类中的equals()方法用的是Object,所以以上的方法严格来讲已经不叫覆写,叫重载。

2.3 Object接口引用数据类型

在之前的分析来讲Object可以接收任意的对象,从结构上来讲Object是所有类的父类,但是Object概念并不仅仅局限于此,他已接收所有的引用数据类型,包括:接口、数组。

使用Object类接收数组,数组和Object没有任何明确的关系。

public class TestDemo4{
	public static void main(String args[]){
		Object obj = new int []{1,3,4};
		int data [] = (int [])obj;//向下转型
		for(int i = 0 ;i < data.length ; i++){
			System.out.println(data[i]);
		}
	}
}

接收接口对象,从接口的定义而言,它是不能去继承一个父类的,但是由于接口依然属于引用类型,所以即使没有继承类,也可以使用Object接收。

interface Message{}
class MessageImpl implements Message{//定义接口子类
	public String toString(){
		return "Hello World";
	}
}
public class TestDemo5{
	public static void main(String args[]){
		Message msg = new MessageImpl();//向上转型
		Object obj = msg;//向上转型
		Message temp = (Message) obj;//向下转型
		System.out.println(temp);//toString()
	}
}

从代码上讲,以上只能算是一个固定的操作概念,不过从实际来讲,因为有了Obejct类的出现,所有的操作就可以达到统一,那么之前的链表程序,就应该变得很方便了。所有的数据都使用Object接收,所有的对象比较(删除、查找)都可以使用equals()。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。