一、多态
1、多态的涵义
多态:可以理解为事物存在的多种体现形态
多态字面上的意思就是多种形态。在面向对象语言中,我们可以将函数的形参定义为一个父类类型,而在真正调用该函数时这个父类类型的所有子类对象都可以传入,根据传入的子类对象不同函数可以运行处多种形态。
简而言之:多态就是父类引用指向子类对象。
人:男人,女人
动物:猫,狗
猫 x=new 猫();
动物x=new 猫();
1、多态的体现:
父类的引用只想了自己的子类对象
2、多态的前提:
必须是类与类之间有关系。要么继承,要么实现
通常还有一个前提:存在覆盖。
3、多态的好处:
提高程序的扩展性
4、多态的应用:
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
public class duotai
{
public static void main(String[] args)
{
cat c=new cat();
c.eat();
dog d=new dog();
d.eat();
function(new dog());
}
public static void function(animal a)
{
a.eat();
}
}
class cat extends animal
{
public void eat()
{
System.out.println("吃鱼");
}
public void catchmouse()
{
System.out.println("抓老鼠");
}
}
class dog extends animal
{
public void eat()
{
System.out.println("吃骨头");
}
public void kanja()
{
System.out.println("看家");
}
}
abstract class animal
{
public abstract void eat();
}
在多态成员函数的特点;
在编译时期:
参阅引用型变量所属的类中是否有调用的方法,如果又,编译通过 如果灭有则编译失败
在运行时期:
参阅对象所属的类中是否有调用的放啊。
总结:多态成员函数时,编译看左边,运行看右边。
在多态成员变量时:
无论编译还是运行,都看左边
在多态中静态成员函数的特点:
无论编译和运行,都参考左边。静态方法是不需要对象的。
如下代码体现:
public class 特点
{
public static void main(String[] args)
{
//zi z=new zi();
//z.method1();
//z.method2();
//z.method3();
fu f=new zi();
//System.out.println(f.num);
f.method4();
zi z=new zi();
z.method4();
// System.out.println(z.num);
}
}
class fu
{
int num=5;
void method1()
{
System.out.println("fu method");
}
void method2()
{
System.out.println("fu method2");
}
static void method4()
{
System.out.println("fu method4");
}
}
class zi extends fu
{
int num=8;
void method1()
{
System.out.println("zi method1");
}
void method3()
{
System.out.println("zi method3");
}
static void method4()
{
System.out.println("zi method4");
}
}
转型
把一个子类当做父类来用的时候,不能调用子类特有方法。
因为编译时编译器会做语法检查,看到变量是父类类型那么就会到父类中查找是否有该方法,没有则报错。
这种情况下,就需要强制类型转换,将父类类型强转成子类类型。
以(子类名)变量名形式进行强制类型转换
强制类型转换时,无论类型是否匹配编译都不会报错,但如果类型不匹配运行会报错,我们可以使用instanceof进行判断,编译时预知错误。
在子类当做父类来用时,不能调用特有方法,如果一定要调用,就需要强制类型转换回子类。在做转换时最好instanceof判断一下类型是否匹配。
public class trans
{
public static void main(String[] args)
{
animal a=new cat();//类型提升,向上转型。
a.eat();
((cat) a).catchmouse();
//如果想要调用猫的特有方法是,如何操作
//强制将父类的 引用,转成子类类型。
cat c=(cat)a;//向下转型
c.catchmouse();
}
}
二、内部类(InnerClass)
1、类中的内部类
在类里面定义的类称之为内部类(Inner Class),内部类是外部类的一个成员。
内部类必须创建外部类对象才能使用。
创建内部类对象时必须先创建一个外部类对象,通过一个外部类对象才能创建内部类对象。
外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
内部类可以直接访问外部类的成员,而外部类不能直接访问内部类的成员。访问方式:外部类名.this.成员名
内部类可以访问外部类成员,因为在使用内部类时一定会有外部类对象,且只对应一个。
外部类不能访问内部类成员,因为在使用外部类时有可能还没有创建内部类对象。
如果一定要在外部类中使用内部类成员,那么需要创建内部类对象,通过对象来访问。
内部类中不能定义静态成员。
因为内部类需要创建外部类对象才能使用,static的本意是不创建对象就能使用,这是矛盾的。
内部类的class文件名为:外部类名.内部类名.class
2、局部内部类
内部类定义在局部时:
(1)不可以被成员修饰符修饰
(2)可以直接访问外部类中的成员,因为持有外部类中的引用
但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量
public class innerclass
{
public static void main(String[] args)
{
new oute().method(7);//进栈后出栈了,
new oute().method(8);
}
}
class oute
{
int x=3;
void method(final int a)
{
final int y=4;
class inner
{
void funtion()
{
System.out.println(a);
}
}
new inner().funtion();
}
}
3、匿名内部类
匿名内部类其实就是内部类的简写格式
定义匿名内部类的前提:
(1)内部类必须是继承一个类或者实现一个借口。
(2)匿名内部类的格式:new 父类或者借口(){定义子类的内容}
(3)匿名内部类就是一个匿名子类对象。
(4)匿名内部类中定义的方法最好不要超过3个。
* */
public class 匿名内部类
{
public static void main(String[] args)
{
new out1().function();
}
}
abstract class absdemo
{
abstract void show();
}
class out1
{
i nt x=3;
/*
class inner extends absdemo
{
void show()
{
System.out.println("method.."+x);
}
}
*/
public void function()
{
//new inner().show();
//new inner().show();
new absdemo()//
{
void show()
{
System.out.println("x="+x);
}
void abc()
{
System.out.println("show.."+x);
}
}.abc();
}
}
4、静态内部类
被static修饰一个类中的内部类。
静态内部类不用创建外部类对象就可以直接创建对象。
外部类名.内部类名 变量名 = new 外部类名.内部类名();
静态内部类可以定义静态成员。
因为静态内部类可以直接使用,无需创建外部类对象。
静态内部类中不能访问外部非静态成员。
因为创建静态内部类不需要外部类对象,也就是有可能没有创建外部类对象,使用外部类成员必须有外部类对象。
当内部类定义在外部类的成员位置时,而且非私有,可以在外部其他类中
可以直接建立内部咧对象。
静态内部类只能访问外部类中的静态成员。出现的访问受限
在外部其他类中,如何直接访问static内部类的成员呢?
out.inner.funtion();
当内部类中定义了静态成员,那么该内部类也必须是静态的。
*/
public class static内部类
{
public static void main(String[] args)
{
new out.inner().function();
}
}
class out
{
private static int x=3;
static class inner
{
static void function()
{
System.out.println("inner.."+x);
}
}
class inner2
{
void show()
{
System.out.println("inner2");
}
}
public static void method()
{
inner.function();
}
}
5、内部类访问规则
内部类可以直接访问外部类中的成员,包括私有
外部类要访问内部类,必须要建立内部类对象。
内部类之所有能访问外部类的成员,是因为内部类中持有了一个外部类中的引用outer.this
public class 内部类访问规则
{
public static void main(String[] args)
{
// outer out=new outer();
//out.method();
//直接访问内部类中的成员。
outer. inner in=new outer().new inner();
in.function();
}
}
class outer
{
int x=3;
class inner//内部类,当内部类在外部类成员位置上时,可以被私有
{
//int x=4;
void function()
{
//int x=6;
System.out.println("inner;"+x);//内部类之所有能访问外部类的成员,是因为内部类中
//持有了一个外部类中的引用。outer.this
}
}
void method()
{
//System.out.println(x);
inner in=new inner();
in.function();
}
}