文章标题

面向对象四

一、多态
定义:事物存在的多种表现形式
例如:动物中猫和狗
猫这个对象对应的类型是猫类型 猫 m = new 猫();
而猫是动物中的一种,所以也可以把猫称为动物,也就是说让父类引用指向子类对象 动物 d = new 猫();
多态的表现形式:
父类的引用指向了子类对象
父类的引用也可以接收该父类类型的对象
多态的前提:
必须类与类之间存在关系,要么继承要么实现
要存在覆盖(复写)
多态的好处:
多态的出现大大的提高了程序的扩展性
多态的弊端:
多态虽然提高了程序的扩展性,但是只能使用父类的引用访问父类的成员
多态的应用:
多态的出现代码中的特点:
在多态中成员函数的特点(非静态)
在编译时期:参阅引用型变量是否有调用的方法,如果有,则编译通过
在运行时期,参阅对象所在的类中是否有调用的方法
简单一句话:编译看左边,运行看右边
白话:就是当父类引用指向子类对象时,如果调用的方法父类中有,就编译通过,没有就报错,如果有再看子类中是否重写该方法,如果重写,不言而喻肯定运行的是子类中的内容
在多态中成员变量的特点:无论编译还是运行,都参考左边
在使用多态调用成员变量时,如果父类和子类中拥有相同名称的成员变量时,左边为父类,那么调用的就是父类中的成员变量,如果左边为子类,那么就调用子类中的成员变量
在多态中静态成员的特点:无论编译还是运行都参考左边
一样道理,静态只要类一加载就存在了,是不需要使用对象的,所以谁调用就运行谁
多态的表现形式:
[java] view plain copy print?
abstract class Animal
{
//定义为抽象方法,要求子类必须实现,因为只要是动物,都具备吃的行为
public abstract void 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 kanHome(){
System.out.println(“狗看家”);
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
/*
Cat c = new Cat();
c.eat();
Dog d = new Dog();
d.eat();
*/
/*
发现这样写会比较麻烦,因为每出现一种动物想要调用该动物的eat()方法都要建立该动物对象,有没有简单一点的方法呢?
因为不管是猫还是狗都是动物,都具备eat()方法,那我能不能直接让动物指向自己的子类呢?因为子类复写了父类中的方法,当使用父类引用指向子类对象调用父类方法时,调用的还是子类的方法
*/
function(new Cat());
function(new Dog());
public void function(Animal a){ //Adimal a = new Cat(); 向上转型
a.eat();
}
/*
但是发现这样写完之后发现没法调用子类特有的方法了,因为动物中是没有子类特有的行为的,怎么办呢?
因为动物不具备猫和狗特有的行为,那么我们能不能使用子类去调用自己特有的方法呢?

        向下转型: 
        public void function(Animal a){ 
            a.eat(); 
            if(a instanceof Cat){    //判断传入的对象类型 
                Cat c = (Cat) a;    //把动物强制转换成猫 
                c.catchMouse(); 
            } 
            else if(a instanceof Dog){ 
                Dog d = (Dog) a; 
                d.kanHome(); 
            } 
        } 
    */  
}  

}
二、内部类
定义:将一个类定义在另一个类的里面,对里面那个 类就称为内部类(内置类,嵌套类),一个类可以定义多个内部类。
内部类访问规则:
1、内部类可以直接访问外部类的成员,包括私有化成员
2、外部类要访问内部类必须要创建内部类对象
访问格式:
1、当内部类定义在外部类的成员位置上时,并且非私有化,
注:当内部类定义在外部类的成员位置上时,是可以被private static成员修饰符修饰的,被static修饰的内部类只能访问外部类中的静态成员
1.1、在本类内部访问内部类
[java] view plain copy print?
class Demo
{
//外部类成员变量
int num = 5;
//内部类
class Inner
{
//内部类成员函数
public void show(){
System.out.println(“调用内部类show方法”);
}
}
//外部类成员函数
public void function(){
//创建内部类对象调用内部类方法
Inner in = new Inner();
in.show();
}
}
注:如果内部类中有同名称的变量,在内部类中调用外部类成员变量时,则运行的是内部类中成员变量的值(其实就是省略了this),而当要访问外部类成员变量时,则需要标识,格式:外部类.this.要调用的变量名
1.2、在外部其他类中访问内部类
[java] view plain copy print?
//在外部其他类中访问内部类
class Outer
{
int x = 5;
//内部类
class Inner
{
public void show(){
System.out.println(“调用内部类方法”);
}
}
public void function(){
System.out.println(“Outer的方法”);
}
}
class Demo
{
public static void main(String[] args)
{
//在其他类中直接访问内部类
/*
因为不确定到底有几个Inner类,所以创建内部类对象时要指明要创建的内部类
格式 外部类.内部类 变量名 = new 外部类类名().new 内部类类名();
*/
Outer.Inner in = new Outer().new Inner();
}
}
注:如果内部类中有同名称的变量,在其他外部类中调用内部类成员变量时,如果内部类中有该变量并没有私有化,则运行的是内部类中成员变量的值,如果没有,则运行该内部类所在的外部类中的没有私有化的成员变量的值
2、当内部类定义在成员位置上并被private或static所修饰时
注:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的
2.1、在外部其他类中,直接访问static内部类的非静态成员

[java] view plain copy print?
class Outer
{
int x = 5;
//静态内部类
static class Inner
{
//内部类中的非静态成员方法
public void show(){
System.out.println(“调用内部类方法”);
}
}
public void function(){
System.out.println(“Outer的方法”);
}
}
class Demo
{
public static void main(String[] args)
{
//在其他类中直接访问静态内部类中的非静态方法
new Outer.Inner().show();
}
}
2.2、在外部其他类中,直接访问static内部类的静态成员
[java] view plain copy print?
class Outer
{
int x = 5;
//静态内部类
static class Inner
{
//内部类中的静态成员方法
public static void show(){
System.out.println(“调用内部类方法”);
}
}
public void function(){
System.out.println(“Outer的方法”);
}
}
class Demo
{
public static void main(String[] args)
{
//在其他类中直接访问静态内部类中的静态方法
Outer.Inner().show();
}
}
3、当内部类定义在局部位置上时
1、不可以被成员的修饰符所修饰
2、可以直接访问外部类中的成员,因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量
[java] view plain copy print?
class Outer
{
int num = 5;
//外部类成员函数
public void function(){
int x = 3;
/*内部类定义在局部位置上,不可以被static、private所修饰,
此时可以访问成员变量num,但是不可以访问局部变量x,因为x没有被 final 所修饰
如果代码改为:
public void function(final int x){
class Inner
{
public void show(){
System.out.println(“调用内部类方法”);
}
}
}
就可以访问了,这样写有一个特点,就是调用function并传参后x的值就固定了,不可以在进行赋值操作了
*/
class Inner
{
public void show(){
System.out.println(“调用内部类方法”);
}
}
}
}

什么时候使用内部类呢?
当描述事物,而事物的内部还有事物,该事物用内部类来描述,因为内部事物在使用外部事物的内容
三、匿名内部类
定义:其实就是内部类的简写格式
定义匿名内部类的前提:内部类必须是继承一个类或者实现接口
匿名内部类的格式:new 父类或者接口(){定义子类的内容}
注:1、其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。 可以理解为带内容的对象
2、匿名内部类中定义的方法最好不要超过3个
[java] view plain copy print?
interface AbsDemo
{
public void show();
}
class Outer
{
//有名内部类
/*
class Inner implements AbsDemo
{
public void show(){
System.out.println(“有名内部类”);
}
}
public void function(){
AbsDemo ab = new Inner();
ab.show();
}
*/
//匿名内部类
public void function(){
new AbsDemo(){
public void show(){
System.out.println(“匿名内部类”);
}
}.show();
/*
因为是匿名内部类,所以是没有名字的,只能通过创捷父类或接口来建立子类对象,完成复写
*/
}
}

class
{
public static void main(String[] args)
{
System.out.println(“Hello World!”);
}
}
小练习:
[java] view plain copy print?
//根据已有代码补全程序,要求使用匿名函数
/*已有代码:
interface Inner
{
public abstract void method();
}
class Test
{
public static function(){}
}
class Demo
{
public static void main(String[] args)
{
Test.function().method();
}
}

*/

class Demo
{
public static void main(String[] args)
{
//Test.function():Test类中有一个静态的方法function。
//.method():function这个方法运算后的结果是一个对象。而且是一个Inter类型的对象。
//因为只有是Inter类型的对象,才可以调用method方法。
Test.function().method();
}
}
//使用匿名对象
interface Inner
{
public abstract void method();
}
class Test
{
public static Inner function(){
return new Inner(){
public void method(){
System.out.println(“重写了方法”);
};
}
}
}
/*
不使用匿名对象
interface Inner
{
public abstract void method();
}
class Test
{
class Util implements Inner{
public void method(){
System.out.println(“重写了方法”);
}
}
public static Inner function(){
return new Util();
}
}
}
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值