抽象类的匿名子类

package test;


public class Test {
	
	public static void main(String[] args) {
		worker w=new worker();
		method1(w);//对象是有名的,是w,类是有名的,是worker。所以为非匿名类非匿名对象
		method1(new worker());//非匿名的类匿名的对象
		
		Person p=new Person() {
			
			@Override//这里也说明了创建的类是Person的子类,注意重写相关的方法
			public void eat() {
				System.out.println("吃东西");
			}
			
			@Override
			public void breath() {
				System.out.println("呼吸");
			}
		};//是new了一个对象,但不是new了一个抽象类的对象,创建了一个匿名(这个类没有名)子类(是Person的子类)对象,对象名为p
		
		method1(p);//会调用对象重写的方法,还涉及到了多态的使用
		
		//造匿名子类的匿名对象
		method1(new Person() {

			@Override//这里也说明了创建的类是Person的子类,注意重写相关的方法
			public void eat() {
				System.out.println("吃好吃的东西");
			}
			
			@Override
			public void breath() {
				System.out.println("呼吸新鲜空气");
			}
		});
    }
	public static void method1(Person p) {
		p.eat();
		p.walk();
	}
}
abstract class Person{//抽象类也可以继承,比如Person是可以继承别的类的
	String name;
	int age;
	
	public Person() {
		
	}
	
	public Person(String name,int age) {
		this.name=name;
		this.age=age;
	}
	
	public abstract void eat();
	
	public abstract void breath();
	
	public void walk() {
		System.out.println("人走路");
	}
}
class worker extends Person{

	@Override
	public void eat() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void breath() {
		// TODO Auto-generated method stub
		
	}
	
}

如果不想用匿名子类的,可以显示的给抽象类提供子类

<think>我们正在讨论Java中的匿名内部类和匿名对象。根据用户的问题,用户想理解并创建匿名子类匿名对象。在Java中,匿名子类通常是通过继承一个类(通常是抽象类或具体类)并立即创建实例来实现的,而不显式地声明一个子类。同样,匿名对象是指没有显式命名的对象,即直接使用new创建的对象而没有将其赋值给变量。 参考引用: - 引用[2]提到:父类Object生成一个匿名子类子类中有新定义的test方法,再new一个匿名对象,调用对象的test方法。 - 引用[3]提供了一个代码示例:通过new Normal()创建了一个匿名子类,并在其中添加了两个新方法func和func1,然后直接调用func1方法。 - 引用[4]展示了Person和Student类的继承关系,但用户的问题是关于匿名子类,因此我们可以参考如何通过匿名子类来扩展一个类。 步骤: 1. 选择一个已有的类(可以是具体类或抽象类,但抽象类需要实现抽象方法)。 2. 使用new 类名() { ... }的语法,在花括号内提供子类的实现(可以重写父类方法或添加新方法)。 3. 由于是匿名对象,我们可以直接调用其方法(如引用[3]中的.func1())或者将其作为参数传递。 注意:匿名子类不能添加新的非final的构造方法,因为匿名类没有类名,所以无法通过构造方法名来调用。通常我们通过实例初始化块或直接调用父类构造方法来初始化。 示例代码: 假设我们有一个简单的类Normal(如引用[3]所示): ```java class Normal { public void start() { System.out.println("S"); } } ``` 我们可以创建Normal的匿名子类匿名对象: ```java public class Test { public static void main(String[] args) { // 创建Normal的匿名子类匿名对象,并调用新方法func1 new Normal() { // 可以重写父类方法 @Override public void start() { System.out.println("Overridden start"); } // 添加一个新方法 public void func1() { System.out.println("func1 in anonymous subclass"); } }.func1(); // 直接调用新方法 // 注意:通过这种方式,我们只能调用在父类中声明的方法或者通过多态(重写)的方法,但是这里我们直接调用了子类新增的方法func1,因为我们在创建对象后立即调用了它。 // 但是,如果我们想调用重写的方法start,可以这样做: new Normal() { @Override public void start() { System.out.println("Overridden start"); } public void func1() { System.out.println("func1 in anonymous subclass"); } }.start(); // 调用重写的方法 } } ``` 但是需要注意的是,匿名子类中新增的方法在外部是不可见的,除非我们通过匿名子类内部的其他方法(比如重写的方法)来调用,或者像上面那样在创建对象后立即调用(因为此时表达式返回的是匿名子类的对象,所以可以调用新增的方法)。但是,如果我们把匿名子类的对象赋值给父类的引用,那么通过父类引用只能调用父类中声明的方法,无法调用子类新增的方法。 因此,创建匿名子类匿名对象并调用其特有方法的唯一方式就是像上面那样在创建后立即调用(通过点操作符直接调用),或者通过内部的其他方法间接调用。 另外,如果父类是抽象类,我们需要在匿名子类中实现所有的抽象方法。 例如,有一个抽象类Animal: ```java abstract class Animal { public abstract void makeSound(); } ``` 创建匿名子类匿名对象: ```java public class Test { public static void main(String[] args) { // 创建Animal的匿名子类匿名对象,并调用makeSound方法 new Animal() { @Override public void makeSound() { System.out.println("Meow"); } }.makeSound(); } } ``` 总结: 在Java中创建匿名子类匿名对象的步骤: 1. 使用`new 父类构造器() { ... }`的语法,在花括号内定义子类的成员(重写方法或新增方法)。 2. 由于是匿名对象,我们可以直接通过点操作符调用其方法(包括重写的方法和新增的方法,但注意作用域)。 3. 如果父类是抽象类,则必须实现所有抽象方法。 注意事项: - 匿名子类不能有显式的构造方法,但可以使用实例初始化块来初始化:`{ ... }`。 - 匿名子类中新增的方法在外部只能通过创建对象后立即调用的方式使用(因为此时表达式的类型是匿名子类类型),如果通过父类引用则无法调用。 用户问题:我想理解并创建匿名子类匿名对象 因此,我们通过示例和解释来回答。 最后,生成相关问题。</think>### Java中创建匿名子类匿名对象 在Java中,匿名子类是指**不显式声明子类名**,直接通过继承父类并重写方法的方式创建的子类匿名对象则是**不通过变量名引用**,直接通过`new`创建的对象。结合两者即可创建匿名子类匿名对象,语法如下: ```java new 父类构造器() { // 子类重写方法或新增方法 }.方法调用(); ``` #### 具体实现步骤 1. **选择父类**:可以是具体类或抽象类(需实现抽象方法) 2. **重写方法**:在`{}`内重写父类方法或添加新方法 3. **直接调用**:通过链式调用直接执行方法匿名对象特性) #### 代码示例 ```java class Animal { void sound() { System.out.println("动物发出声音"); } } public class Main { public static void main(String[] args) { // 创建匿名子类匿名对象并调用方法 new Animal() { // 匿名子类 @Override void sound() { // 重写父类方法 System.out.println("喵喵叫 (匿名子类实现)"); } void jump() { // 子类新增方法 System.out.println("猫咪跳跃"); } }.jump(); // 匿名对象直接调用方法 } } ``` #### 执行结果 ``` 猫咪跳跃 ``` #### 关键说明 1. **匿名子类本质**: - 编译器会自动生成形如`Main$1.class`的子类文件 - 继承自指定父类(此处为`Animal`) - 包含所有重写和新增的方法[^1] 2. **匿名对象限制**: ```java // 正确:直接调用新增方法 new Animal(){ ... }.jump(); // 错误!匿名对象无法二次调用 Animal a = new Animal(){ ... }; // 需变量名引用才能复用 ``` 3. **抽象类场景**: ```java new AbstractClass() { @Override void mustImplement() { ... } // 必须实现抽象方法 }.mustImplement(); ``` #### 典型应用场景 1. 快速覆盖方法实现(如GUI事件监听) 2. 临时扩展类功能(无需创建单独子类) 3. 简化测试代码(快速模拟实现) > 提示:匿名子类中新增的方法在父类引用中不可见,这是多态性的设计限制[^2][^4]。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值