黑马程序员——Java要点笔记——面向对象(五)

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

day10 02-面向对象-多态-概述

1、多态定义:某一类事物的多种存在形式。

2、对象的多态性,代码示例

class 动物{
   
}
class 猫 extends 动物{
   
}
class 狗 extends 动物{
   
}

m = new 猫();

动物 d = new 动物();//父类引用指向子类对象

 

小猫!小动物!你原来管小猫叫小猫,后来你管小猫叫小动物,有错吗?没错的呀!

猫这类事物既具备猫的形态,又具备着动物的形态。这就是对象的多态性。

简单说,就是一个对象对应着不同类型。

       多态在代码中的体现:父类或者接口的引用,指向其子类的对象。

day10 03-面向对象-多态-好处

1、代码示例

简略为下图:

2、多态的好处

提高了代码的扩展性,前期定义的代码可以使用后期的内容。

如上例:我前期定义了一个Animal类。我可以拿Animal接受任何,后期所创建的Animal的子类对象。我后期可以随便来什么动物,小鸡、小鸭,我前期有了Animal,后期只要是动物,尽管来。

day10 04-面向对象-多态-弊端&前提

1、多态的前提:前期定义的内容不能使用(调用)后期子类的特有内容。

2、多态的前提:

①必须有关系,要么继承,要么实现。(因为你要拿父类或接口来接收,后期定义的子类或实现类对象)

②要有覆盖(有覆盖,执行的才是后面各个子类所应该执行的内容。比如上例中的eat()方法。小狗是啃骨头,小猫是吃鱼)。调用通用覆盖方法,运行子类函数。

day10 05-面向对象-多态-转型1

1、代码示例

       这时,猫一旦提升为动物,访问上就出现了局限性,就不能访问猫这个子类所特有的功能了。

作用:可以限制对特有功能的访问。提高扩展性。

专业点讲:向上转型。猫已经向上荣升为动物了。

2、那么问题来了,我如果想继续用猫的特有功能,怎么办?你可以将该对象进行向下转型。

      

猫一定是动物,但是动物就一定是猫吗?不一定!这种判断,要看右边new的实例到底是什么。

3、注意:对于转型,自始至终都是子类对象在做着类型的变化。

day10 07-面向对象-多态-类型判断-instanceof

1、观察以下代码

2、别人往这个函数里面传什么动物,你根本就不知道。那么你向下转成猫,就会报错。怎么解决?解决方式就是在向下转型前,加一个判断。他是猫你才转,他不是猫你别瞎转。


在向下转型之前,通常进行instanceof的判断,增加程序的健壮性。

day10 08-面向对象-多态-成员变量

1、代码示例

class Fu{
    int num=3;
}
class Zi extends Fu{
    int num=4;
}
public class Demo11 {
    public static void main(String[] args){
       Zi z=new Zi();
       System.out.println(z.num);
       Fu f=new Zi();
       System.out.println(f.num);
    }
}

运行结果:4

          3

2、new Zi()里面有俩num,一个是父类的num,一个是子类的num。子类对象提升为了父类对象,那么就找父类的num。不覆盖!覆盖只发生在函数上。若class Fu{},再执行下面,运行结果:报错,找不到num。

3、多态时,成员的特点:

①成员变量:编译时,参考引用型变量所属类中是否有调用成员变量。有,编译通过;没有,编译失败。

运行时,参考引用型变量所属的类中是否有调用的成员变量,并运行该所

属类中的成员变量。

4、简单说,编译和运行都参考等号的左边。

day10 09-面向对象-多态-成员变量

1、此为重点!必须的重点!

2、代码示例

class Fu{
    void show(){
       System.out.println("Fushow");
    }
}
class Zi extends Fu{
    void show(){
       System.out.println("Zishow");
    }
}
public class Demo11 {
    public static void main(String[] args){
       Fu f=new Zi();
       f.show();
    }
}

运行结果:Zi show

3、如果父类对象中没有show()可不可以?不可以!编译失败。

4、若子类中无show(),一个super指向父类,运行结果:Fu show

5、多态时,成员的特点:②成员函数(非静态)

       编译时,参考引用型变量所属的类中是否有调用的函数。有,编译通过。没有,编译失败。

       一有多态,向上转型,将子类型隐藏,就不能使用子类型的特有方法了。

       运行时:参考对象所属的类中是否有调用的函数。

       简单来说:编译看左边,运行看右边。右边没有这个方法,super到超类。

day10 10-面向对象-多态-静态函数

1、代码示例

class Fu{
    static void method(){
       System.out.println("Fu staticmethod");
    }
}
class Zi extends Fu{
    static void method(){
       System.out.println("Zi staticmethod");
    }
}
public class Demo11 {
    public static void main(String[] args){
       Fu f=new Zi();
       f.method();
    }
}

       运行结果:fu static method

2、非静态方法,必须依赖对象来调用。

3、对象的多态性。静态方法需要用对象吗?直接Fu.method();Zi.method();哦了。

4、多态时,成员的特点:③静态函数

编译时:参考引用型变量所属的类中是否有调用的静态方法。

运行时:参考引用型变量所属的类中是否有调用的静态方法。

简单说:编译和运行都看左边。

5、其实对于静态方法,是不需要对象的。那我就根本不用管它new的是什么了。直接用类名(左边)调用即可。

day10 11-面向对象-内部类-概述

1、内部类:将一个类定义在另一个类里面,对里面那个类就成为内部类。

2、一个内部类写好了之后,他应该有所属才对,谁的内部类。

class Outer{
    class Inner{
      
    }
}
class Outer2{
    class Inner{
      
    }
}
public class Demo12 {
    public static void main(String[] args) {
 
    }
}

3、内部类的访问特点:

①内部类可以直接访问外部类中的成员。

②外部类要访问内部类,必须建立内部类的对象。

4、一般用于类的设计:分析事物时,发现该事物描述中还有事物。而且这个事物还在访问被描述事物的内容。这时,就把还有的事物定义成内部类来描述。

5、代码示例

class Outer{
    private int num=3;
    class Inner{
       void show(){
           System.out.println("showrun..."+num);
       }
    }
    public void method(){
       Inner in=new Inner();//method()是外部类的方法,外部类访问内部类,必须建立内部类的对象。
       in.show();
    }
}
class Demo12{
    public static void main(String args[]){
       Outer out=new Outer();
       out.method();
    }
}

运行结果:show run…3

day10 12-面向对象-内部类-修饰符

1、在其他类访问另一个类中的内部类。代码示例:

class Outer{
    private int num=3;
    class Inner{
       void show(){
           System.out.println("showrun..."+num);
       }
    }
    public void method(){
       Inner in=new Inner();
       in.show();
    }
}
class Demo12{
    public static void main(String args[]){
       Outer.Inner in=new Outer().new Inner();
       in.show();
    }
}

运行结果:show run…3

2、


3、如果内部类是静态的,相当于一个外部类(static可以用来修饰类——static class Inner),那么内部类所使用的东西也要是静态的。

4、


5、如果内部类是静态的,成员是静态的。如果对内部类中定义了静态成员,该内部类也必须是静态的。否则报错:内部类当中不能有静态声明。

6、

day10 13-面向对象-内部类-细节

1、代码示例

class Outer{
    int num=3;
    class Inner{
       int num=4;
       void show(){
           int num=5;
           System.out.println(num);
       }
    }
    public void method(){
       new Inner().show();
    }
}
class Demo12{
    public static void main(String args[]){
       new Outer().method();
    }
}

运行结果:5(栈内存中有,先用栈里的)

2、如果我想打印4,show方法里写System.out.println(Inner.this.num);

如果我想打印3,show方法里写System.out.println(Outer.this.num);

3、你写this.num,前面隐含了一个本类对象,即Inner.this.num。你要打印外部类的Outer.this.num。只写this.num,打印的也是4。

4、为什么内部类能直接访问外部类中的成员?

       那是因为内部类持有外部类的引用——外部类名.this

day10 14-面向对象-内部类-局部内部类

1、内部类可以存放在局部位置上。

2、代码示例

class Outer{
    int num=3;
    void method(){
       int x=9;
       class Inner{
           void show(){
              System.out.println("show..."+x);
           }
       }
       Inner in=new Inner();
       in.show();
    }
}
public class Demo13 {
    public static void main(String[] args) {
       new Outer().method();
    }
}

内部类放到了方法体中。但是此处报错:从内部类中访问局部变量x,需要x被声明为最终类型。(final)

void method(){
       final int x=9;
       class Inner{
           void show(){
              System.out.println("show..."+x);
           }
       }
       Inner in=new Inner();
       in.show();
    }

运行结果:show…9

3、注意:内部类在局部位置上只能访问局部中被final修饰的局部变量。

day10 15-面向对象-匿名内部类-概述

1、匿名内部类,必须有前提,内部类必须继承或者实现一个外部类或者接口。

2、匿名内部类顾名思义——他没有名字。没名字你new什么?所以才有了这些前提。

3、代码示例

abstract class Demo{
    abstract void show();
}
class Outer{
    int num=4;
    public void method(){
       new Demo(){
           void show(){
              System.out.println("show..."+num);
           }
       }.show();
    }
}

这里面的new demo是匿名内部类。这里面同时覆盖了show(),同时也顺便调用了show()。在调用show方法时,由于匿名内部类中无num。一个Outer.this,去外部类去找。

4、匿名内部类,其实就是一个匿名子类对象。

5、格式:new 父类or接口(){子类内容}

6、主方法中:new Outer().method();

       运行结果:show…4

day10 17-面向对象-匿名内部类-细节

1、代码示例:

class Outer{
    void method(){
       Object obj=new Object(){
           public void show(){
              System.out.println("showrun");
           }
       };
       obj.show();
    }
}
public class Demo14 {
    public static void main(String[] args) {
       new Outer().method();
    }
}

2、obj.show()这句挂了,因为show()是子类特有方法。因为匿名内部类这个子类对象被向上转型为了Object类型了,这样就不能再使用子类的特有方法了。

day10 18-面向对象-对象的初始化过程

1、代码示例

class Fu{
    int num=9;
    {
       System.out.println("Fu");
    }
    Fu(){
       super();
       //显示初始化
       //构造代码块初始化
       show();
    }
    void show(){
       System.out.println("Fushow"+num);
    }
}
class Zi extends Fu{
    int num=8;
    {
       System.out.println("Zi");
    }
    Zi(){
       super();
       //显示初始化
       //构造代码块初始化
       show();
    }
    void show(){
       System.out.println("Zi show"+num);
    }
}
public class Demo15 {
    public static void main(String[] args) {
       new Zi();
    }
}

运行结果:Fu

               Zi show 0

               Zi

               Zi show 8

2、对象的初始化过程


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值