五、虚方法、对象造型与内部类

本文深入解析Java中的多态现象,包括虚方法调用、对象造型、运行时多态及多态的意义。同时,详细阐述内部类的概念,如成员内部类、局部内部类、静态内部类和匿名内部类的特性和使用场景。
  • 一、虚方法调用

严格意义上来说,在Java语言中是没有虚方法的,但是这种现象会出现,而且没有一种专有名词来表达,所以使用C++语言中的术语来表达这种现象

正常的方法调用

        Person p = new Person();
  	p.showName();
  	Student s = new Student();
   	s.showName();

 虚拟方法调用(多态情况下)

    Person p = new Student();
    p.showName(); //实际调用的是Student类的方法

编译时类型和运行时类型        

       运行时类型识别(run-time type identification ,RTTI) 

只有程序运行时才创建对象

  • 二、对象的造型(cast)

所谓对象造型就是Java对象间的类型转换,即:引用类型数据的强制类型转换

Java的对象造型可以分为两种情况: 自动造型;强制造型

Person p = new Student();//向上追溯(自动造型)   抽象的范围广可以自然而然的包含具体的,不需要额外人为的增加条件

Student s = (Student)p;//强制类型转换(强制造型)  将一个抽象的向一个具体的变量上转换,就需要强制类型转换了

对象的造型只用在有继承关系或接口实现的对象之间(即多态)

什么是向上转型、向下转型

对象的强制类型转换也称为向下造型,是将父类类型的对象变量强制地转换为子类类型。

向下转型什么时候能成功: 恢复对象的“本来面目”

在造型前可以使用“instanceof”运算符测试一个对象的类型,可以避免造型异常

数组中是否可以存在不同对象?可以

Person p = new Person();
Student s = new Student();

Object[] os = new Object[2];
os[0] = p;
os[1] = s;

【运行时多态】          

通过一个父类变量发出的方法调用,可能执行的是该方法在父类中的实现,也可能是在某个子类中的实现,这只能在运行时刻根据该变量指向的具体对象确定,这就是运行时多态也称为运行时识别。

【多态的意义】        

Java的多态性,突出的优点是使程序具有良好的可扩展性。

当程序从通用的基础类派生出任意多的新类型(子类),或向基础类中增加更多的方法时,无需修改原有对基础类进行处理的相关程序。并且可以处理这些新的类型,为程序增加新的功能。

  • 三、内部类

允许一个类的定义出现在另一个类中,将处于另一个类中的“寄生类”称为“内部类”(inner class),也称为“类属类”

这样的一组类在逻辑上是一个整体,内部类和外层封装它的类之间存在逻辑上的从属关系

内部类对其封装类(即外部类)的内部成员有访问权限

外部类不能直接访问内部类中定义的非static成员变量

内部类有静态内部类和实例内部类,静态内部类用的非常少基本不用

内部类可以随意使用外部类的方法,外部类要使用内部类的方法必须要创建内部类的对象,通过内部类对象调用

public class Outer1 {
  private int size;
  /* 定义一个内部类,名称为: Inner */
  public class Inner {
    public void doStuff() {
      // 内部类可以访问外部类的私有属性
      size++;
    }
  }
  public void testTheInner() {
    Inner i = new Inner();
    i.doStuff();
  }
}

 实例化内部类的两种方法:

        //---方法一:建议使用这种方式
	Outer.Inner in = new Outer().new Inner();
	//---方法二:
	Outer o = new Outer();
	Outer.Inner I = o.new Inner();
	//如果内部类是static的,也可以用下面方法:
	Outer.Inner in = new Outer.Inner();

注:实例化实例内部类(非静态内部类)的前提是必须先有外部类的实例对象。  

补充说明:

当一个类(A类)中的程序代码要用到另外一个类(B类)的实例对象,而另外一个类(B类)中的程序代码又要访问第一个类(A类)中的成员,将另外一个类(B类)做成第一个类(A类)的内部类,程序代码将会非常容易编写。

【局部内部类】

类的名字只能在定义的范围内使用,除非使用有效的全名;

内部类也可以定义在方法的内部。方法中final类型的局部变量,都可以被局部内部类的方法访问,但是不能访问所在方法中定义的非final类型的局部变量,可以访问外部类的成员变量。(参见下方示例)    

注:方法中的内部类不能用任何访问控制符修饰,方法中定义的内部类只能在该方法中使用。

【内部类分类】

内部类可分为:成员(全局)内部类和局部内部类两种:

  1. 成员内部类:还可细分为:实例内部类和静态内部类两种
    1. 实例内部类:  必须存在外部类的实例;  内部类(包括多重内部类)可以访问所有外部类成员;  外部类必须通过实例访问内部类;  实例内部类不能有静态的成员(成员变量和方法统成为成员); (内部类分类和变量的分类类似)  
    2. 静态内部类:创建实例不用有外部类实例; 可以直接访问外部类的静态成员; 可以有静态的和非静态的成员; 可以直接用外部类.内部类.成员来访问静态内部类的静态成员; 注:静态内部类使用非常少。
  2. 局部内部类:只能在当前方法中使用; 不能包含静态成员; 不能用public、protected、private等修饰局部内部类; 可以访问外部类成员(包括成员变量和方法),所在方法的final类型的输入参数(方法的形参)、方法中定义的使用final关键字修饰的局部变量,成员变量(这里指的是内部类的成员变量); 注:不能访问所在方法中非final类型的形参和方法中非final修饰的局部变量  

【内部类特性】

内部类可以声明为抽象类 ,因此可以被其它的内部类继承。也可以声明为final的。

和外层类不同,全局内部类可以声明为private或protected

全局内部类可以声明为static的,但此时就不能再使用外层封装类的非static的成员变量;

非static的内部类(实例内部类)中的成员不能声明为static的,只有在顶层类或static的内部类中才可声明static成员。

匿名内部类

没有名称的内部类;  没有构造方法,调用父类的构造函数;  只有一种初始化方式就是自由块;

A a = new A(){
		String s="Hello";
		String getS(){return s;}
	};
(new A() 其中“A” 是父类名称, 也可以是接口)

如果一个类仅仅使用一次,那这个类就没有必要编译为class文件存储,此时就可以使用匿名内部类 

内部类的用法:一种封装类型的有效手段;  能够直接访问外部类的成员;

  • 四、修饰符的适用范围

 

class

属性

方法

构建器

自由块

全局内部类

public

Y

Y

Y

Y

 

Y

protected 

 

Y

Y

Y

 

Y

(Default)

Y

Y

Y

Y

Y

Y

private

 

Y

Y

Y

 

Y

final

Y

Y

Y

 

 

Y

abstract

Y

 

Y

 

 

Y

static

 

Y

Y

 

Y

Y

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值