多态和内部类

来源:互联网 发布:纸飞机软件exe 编辑:程序博客网 时间:2024/06/08 04:47
多态:
简单说:同一类事物具备多种形态(就是一个对象对应着不同类型)
猫既具备着猫的形态,又具备动物的形态,这就是对象的多态
方法的多态:重载和重写
狗 名字 = new 狗();
动物 名字 =new 狗 ();
前提:狗是动物中的一种,狗是需要继承于动物的,才可以这样写
多态在代码中的体现:父类或者接口的引用指向其子类对象,这就是多态
转型成父类引用的子类对象不能够调用子类的方法
对象的向上转型:好处:
1、限定了子类的特有方法
2、提高了代码的扩展性
  向下转型的弊端和好处:
       弊端:转化类型的不确定性,如果类型转换错误,那么会出现运行时异常
       好处:能够调用子类的特有功能了
多态的好处:
    提高了代码的可扩展性
 多态的弊端:
    限定了子类的特有功能,父类的引用只能够使用父类中有的方法
 多态的前提:
    1、必须有关系,继承和实现
    2、通常情况下是存在着覆盖(重写)的操作的


多态应用场景:
什么时候使用向上转型?
     当程序需要拓展的时候,或者限定了对对象的方法进行操作的时候
什么时候使用向下转型?
     需要使用子类特有的功能时,要向下转型,但是转型之前必须判断,判断你的引用对象是不是你转


型的类型
instanceof:判断前面的对象是不是属于后面的类型
误区:不能父类对象转换成子类对象
从三个方面看一下多态的特点:
1、成员变量
       简单来说:编译或者运行都看等式的左边
       编译时:
       运行时:
       (一般情况下就在父类继承过来了,就不会再定义相同的属性了。成员变量不存在覆盖。如果父


类中没有那个变量就也不会知道子类中有那个变量了)
2、成员函数
        编译时:看引用型变量所属的类中是否有那个方法
运行时:参考的是子类对象所属类中是否有那个方法,有就调用子类中覆盖的方法,没有就调用


父类中的方法(前提是父类中一定有那个方法)
3、静态函数
       简单来说:编译或者运行都看等式的左边(引用型变量)
       (静态跟对象无关,哪个类调用就调用哪个类的静态函数,静态的都绑定在所属的类中)


Object
object类中有一个equals方法,原来呢是判断引用是不是同一个对象,但是我们可以通过重写来定义新的


判断。compare
equals:
toString :为了对类
getclass方法返回对象所在的类名,字节码文件名
hashCode:返回哈希码值


内部类:
内部类可以直接访问外部类的私有方法
外部类访问内部类成员的时候,创建内部类对象
类是用来描述事物,事物中又有具体事物就用内部类(当然也可以用外部类)
内部类的出现:
这个类和他的外部类联系紧密,和其他类没有关系的时候
一个类想直接访问一个类中的私有属性,
***为什么内部类能够直接访问外部类中的成员呢?
因为内部类中持有一个外部类的引用,外部类名.this
权限修饰符:
外部类:public abstract final
内部类:public default protected private
private修饰内部类时外部类不能直接访问内部类内容
其他的,外部类直接创建内部类对象即可访问
内部类的字节码文件:Outer&Inner.class
创建内部类对象格式:
Outer.Inner   inner =new Outer().new Inner();
静态内部类的特点:
1、如果内部类被定义成了静态类,出现了局限性,只能访问外部类的静态成员,而不能访问非静态成员
2、内部类被static修饰后,内部类随着外部类的加载而加载
3、如果内部类中定义了静态成员,那么这个内部类必须被静态修饰符所修饰,否则,编译失败
      (前提是:这个内部类不是局部内部类)
//一个内部类中有静态方法那么这个类就要是静态类


当内部类是静态的时候:
外部类名.内部类名 对象名 =new 外部类名.内部类名();
调用静态内部类中的非静态方法:
Outer.Inner in =new Outer.Inter();
in.show();
在其他类中调用内部类的静态方法和非静态方法的区别:




局部内部类:
局部内部类定义在方法中
局部内部类不能够定义成静态的(因为内部类持有一个外部类的引用)
//变量是不可控的。常量的值是确定的,所以可以被引用穿出来。
    *****
// 1.局部内部类的作用域:在所在的方法区域中
   2.可以通过多态把内部类的对象经过向上转型传出来
   3.局部内部类不能去访问她所在方法中的变量,原因:第二点;可以访问由final修饰的常量
内部类在局部位置上只能访问局部中被final修饰的局部变量:
答:内部类和外部类其实是属于同一个级别的,内部类不会因为定义在方法中就会随着方法的执行完毕而


跟随者被销毁。所以,如果外部类的方法中的变量不定义final,那么当外部类方法执行完毕的时候就会


被gc了,那么当内部类的某个方法还没执行完,这个时候他所引用的外部变量找不到了
    匿名内部类:
    *****前提:需要实现或者继承外部的一个接口或类的时候,这个时候才可以写成匿名内部类
    要写一个方法,方法中写匿名内部类
    调用匿名内部类步骤:
    1、写外部类,在外面写了一个可继承的抽象类
    2、在外部类中写了一个内部类中实现的方法。
    3、在方法中写匿名内部类
    4、可以在匿名内部类中写入自己的方法和变量,但是可以直接在对象候访问,不能提升类型后访问
    5、匿名内部类也是有局限性的(匿名内部类是一个特殊的局部内部类)
   回调:在方法的参数列表中,传入了抽象类或者接口,然后再该方法调用时,就实现参数列表中的   


接口或者抽象类的方法
   匿名内部类的好处:
   简化书写
   弊端:方法太多的时候影响阅读


   扩展:
   1、 内部类和继承的关系
            1、代码的共享
             2、不要把子类写到父类中当作内部类
   2、不要将内部类继承外部类
   3、内部类可不可以作为父类,让其他类来继承呢?
         可以。
匿名内部类的字节码文件名:外部类名$1.class(第一个匿名内部类,第二个就是 外部类名    


     $2.class 以此类推)
*****对象可以看作是数据的封装体
 
单例设计模式:
解决问题:数据共享(一个类在内存中的唯一性)
思考:怎么保证对象的唯一性?
  1、不要让其他程序去创建该类的对象,因为数据不可控制
  2、不让其他程序创建对象,那就在本类中创建一个对象
  3、对外提供该类创建的对象,让其他程序能够使用
  步骤:
  1、构造函数私有化
  2、在本类中创建一个该类的对象
  3、定义一个方法,返回值是本类的类型,然后其他类就可以通过这个方法获取到本类的对象



  单例模式的延迟加载也叫懒汉式






对象的内存初始化过程:
在子类构造函数中super();下面是显示初始化,然后是 构造代码块初始化
         
0 0
原创粉丝点击