**

多态

**
多态是Java面向对象三大特征的最后一个,在第二篇日志中提到,多态是通过继承/实现来完成的。

所谓的多态就是一个对象的不同的形态。举个例子,我有一只猫,它是是动物类的,同时也是猫咪类的,这就展现了它的两个形态。

我们为什么要使用多态呢?下面一张图展示了多态的好处:

为什么Java里面要有多态 java为什么使用多态_java

再图上我们可以看到,多态的出现让类的使用更加的简单,更加具备面向对象的特征,即只关心调用那个对象不关心具体过程。

我们来看一下多态的代码实现,首先定一个一个父类(Parent类)

public class Parent {

	int num=10;
	
	public void method() 
	{
		System.out.println("Parent方法");
	}
	
	public void showNum() 
	{
		System.out.println(num);
	}
}

子类(Child类)

public class Child extends Parent{
	
	int num=20;
	
	@Override
	public void method() 
	{
		System.out.println("Child方法");
	}
	
	@Override
	public void showNum() 
	{
		System.out.println(num);
	}
	
	public void methodChild() 
	{
		System.out.println("Child特有方法");
	}

}

定义好之后,我们来创建对象,这一步体现了多态

Parent obj=new Child();
//体现了多态性,对象的向上转型

上面的代码体现了多态性:父类引用指向子类对象(接口的形式也可以)。

我们来看一下多态在访问成员变量和成员方法时的注意事项

obj.method();
//调用了method方法(子类父类都有)

结果

Child方法

可以看出obj使用了Child里面的method方法。但是,如果Parent里面没有method方法,那么这条代码错误!

成员变量的访问:
1.直接访问

System.out.println(obj.num);

结果

10//parent

成员变量的访问就是看创建对象时的等号左边是谁,这个是Parent就不可以访问Child里面的num。

2.间接访问

obj.showNum();

结果

20

因为子类已经覆盖重写,所以打印Child里的num。

以上是成员变量和成员方法的访问规则,这里有一条口诀,避免记错:

成员变量访问口诀:编译看左,运行看左

成员方法访问口诀:编译看左,运行看右

这里的左右指的是创建对象时,等号的左右两端。两条口诀的第一句都是一样的,这证明了不管子类有多少变量或方法,想通过多态的形式来体现,等号左边的类一定要有这些方法或者变量。

下面介绍一个非常好用的关键字:instanceof

instanceof关键字可以知道一个父类引用对象本来是什么类型。我们用代码举一个例子(还是使用上面的obj对象)

if(obj instanceof Child)//意思是如果obj是Child类型
	{
		System.out.println("obj是Child类型");
	}
	else
		System.out.println("objb不是Child类型");

结果

obj是Child类型

这里其实蕴涵了一个向下的类型转换(把本来就是Child类型的obj转换成Child类型),多态就是一个向上的类型转换,那么有向上肯定有向下,代码:

Child child=(Child) obj;
child.methodChild();//调用Child特有的方法

结果

Child特有方法

**

final关键字

**
fianl关键字有四种用法,修饰局部变量,修饰成员变量,修饰成员方法,修饰一个类。

四种方法的作用:
1.用final修饰一个类时,代表这个类不可以有子类

2.用final修饰一个成员方法时,代表这个成员方法不可以再被重写,就是最终方法

3.用final修饰一个成员变量时,代表这个成员变量不可以被改变,而且必须赋值,不再有默认值(要么直接赋值,要么通过构造方法赋值)

4.final修饰局部变量,代表这个变量不可以在被改变。

有一点注意事项,final来修饰一个引用类型时,并不意味着该引用类型里面的成员变量的值不可以改变,意味着该引用类型的地址值不可以再改变

例如

final FinalClass people=new FinalClass("gfx");
		
people.getNmae();
		
people.setName("zbh");
		
people.getNmae();

结果

gfx
zbh

但是如果改变地址值

people=new FinalClass();

编译器就会报错。

今天的比较少,下一次更新内部类的使用。