黑马程序员——面向对象(三)

1多态概念

定义:某一类事物的多种表现形式。可以理解为事物存在的多种体现形态。

2多态-扩展性

多态的体现:父类的引用指向了自己的子类对象。父类的引用也可以接受自己的子类对象。 如:Father father=new Sun();
多态的好处:多态的出现大大的提高了程序的扩展性。
多态的前提:必须是类与类之间的关系,要么继承,要么实现。通常还有一个前提,存在覆盖。
多态的弊端:提高了扩展性,但只能使用父类的引用访问父类中的成员。

interface Animal {

    void eat();

}

public class Dog implements Animal {

/*重写父类的方法*/

   public void eat() {

     System.out.println("狗吃骨头");

   }

}

public class Pink implements Animal {

   /* 重写父类的方法 */

   public void eat() {

     System.out.println("猪吃猪饲料");

   } 

}

public class DuoTaiDemo {

   public static void main(String[] agrs) {

     animalEat(new Dog());

     animalEat(new Pink());

   }

 

  /**

   * 用父类来接受子类,那么就可以调用子类和父类相同的方法

   */

   public static void animalEat(Animal animal) {

     animal.eat();

  }

}

结果:

狗吃骨头

猪吃猪饲料

 

3多态-转型

如果想要操作子类特有的方法,怎么办?

强制将父类的引用转成子类类型。如:Father father=new Son();Son son=Sonfather;
但不能这么做:(将父类对象转成子类类型)

Father father=new Father();

Son son=Sonfather;
我们能转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。多态自始自终都是子类对象在做着变化。
判断一个实例是不是某个类型时:a instanceof Son;a是实例名,Son是类名

4、多态-示例

 interface Animal {

   void eat();

}

public class Dog implements Animal {

  /* 重写父类的方法 */

   public void eat() {

     System.out.println("狗吃骨头");

   }

 

  /* 自独有的方法 */

   public void seeDoor() {

     System.out.println("看门");

   }

 

}

public class Pink implements Animal {

 

   /* 重写父类的方法 */

   public void eat() {

     System.out.println("猪吃猪饲料");

   }

  /* 自独有的方法 */

   public void DongDi() {

     System.out.println("猪,gongdi");

   }

 

}

public class DuoTaiDemo {

   public static void main(String[] agrs) {

      animalEat(new Dog());

     animalEat(new Pink());

   }

 

  /**

   * 用父类来接受子类,那么就可以调用子类和父类相同的方法

   */

  public static void animalEat(Animal animal) {

     animal.eat();

    /*instanceof 是判断是否是此类对象,十寸与此类存在某种关系

     * 一般情况下,只有在子类比较少的情况下,才使用此比较的方式,

     * 父类不能调用子类自己独有的方法,必须强制转换成子类对象*/

    if(animal  instanceof Dog){

       Dog dog=(Dog)animal;

       dog.seeDoor();

    }else if(animal instanceof Pink){

       Pink p=(Pink)animal;

       p.DongDi();

    }

  }

}

结果;

狗吃骨头

看门

猪吃猪饲料

猪,gongdi

5多态中成员的特点

在多态中成员函数(非静态)的特点:
在编译时期:参阅引用型变量所属的类是否有调用的方法,如果有,编译通过,如果没有,编译失败。
在运行时期,参阅对象所属的类是否有调用方法。
简单总结:成员函数在多态调用时编译看左边,运行看右边。

public class Fu {

   public int num=5;

  /*静态成员*/

   public static void show(){

     System.out.println("父类的静态的show()方法");

   }

  public void print(){

     System.out.println("父类的非静态的print()方法");

  }

}

public class Zi extends Fu {

   public int num=10;

 

    public static void show(){

      System.out.println("子类的静态的show()方法");

    }

    public void print(){

     System.out.println("子类的非静态的print()方法");

   }

   public static void main(String[] agrs) {

     Fu fz = new Zi();

     fz.show();//父类的,因为是静态的方法

     System.out.println(fz.num);//父类的,因为是常量

     fz.print();//子类的,因为不是静态的

   }

}

结果:

父类的静态的show()方法

子类的非静态的print()方法

涉及面试的环节:

在多态中成员变量和静态函数的特点:无论编译和运行,都参考左边(引用变量所属的类)

6多态的主板示例

需求:电脑运行实例,电脑运行基于主板。

interface PCI

{

public void open();

public void close();

}

 

class MainBoard

{

public void run()

{

System.out.println("mainboard run ");

}

public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。

{

if(p!=null)

{

p.open();

p.close();

}

}

}

 

 

class NetCard implements PCI

{

public void open()

{

System.out.println("netcard open");

}

public void close()

{

System.out.println("netcard close");

method();

}

}

class SoundCard implements PCI

{

public void open()

{

System.out.println("SoundCard open");

}

public void close()

{

System.out.println("SoundCard close");

}

}

 

class DuoTaiDemo5 

{

public static void main(String[] args) 

{

MainBoard mb = new MainBoard();

mb.run();

mb.usePCI(null);

mb.usePCI(new NetCard());

mb.usePCI(new SoundCard());

}

}

7多态的扩展示例

需求:数据库操作,数据是用户信息
1)连接数据库,
2)操作数据库,增删改查
3)关闭数据库连接。

interface UserInfoDao

{

public void add(User user);

 

public void delete(User user);

}

 

class UserInfoByJDBC implements UserInofDao

{

public void add(User user)

{

1,JDBC连接数据库。;

2,使用sql添加语句添加数据。;

3,关闭连接。

}

public void delete(User user)

{

1,JDBC连接数据库。;

2,使用sql添加语句删除数据。;

3,关闭连接。

}

}

 

class UserInfoByHibernate implements UserInfoDao

{

public void add(User user)

{

1,Hibernate连接数据库。;

2,使用sql添加语句添加数据。;

3,关闭连接。

}

public void delete(User user)

{

1,Hibernate连接数据库。;

2,使用sql添加语句删除数据。;

3,关闭连接。

}

}

 

class  DBOperate

{

public static void main(String[] args) 

{

//UserInfoByJDBC ui = new UserInfoByJDBC();

// UserInfoByHibernate ui = new UserInfoByHibernate();

UserInfoDao ui = new UserInfoByHibernate();

ui.add(user);

ui.delete(user);

}

}

 

8Object

Object是所有对象的直接或者间接父类,传说中的上帝。该类定义的肯定是所有类都具备的功能。
Object已经提供了对对象是否相同的比较方法,如果自定义类中也有比较相同的功能,没有必要重新定义,只要沿袭父类中的功能,建立自己特有的比较内容即可,这就是覆盖。

9内部类访问规则

定义:将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类)。

内部类特点:
内部类可以直接访问外部类中的成员,也包括私有。
外部类要访问内部类必须建立内部类对象。
在另一个类中访问内部类方式:外部类.内部类 名称=new 外部类(). new 内部类();
private可以修饰内部类的class前面。
如果内部类和外部类有相同的变量名,则在外部类访问内部类变量时方式:外部类.this.变量名;

10静态内部类

总结访问格式:
1当内部类定义在外部类的成员位置上,而且非私有,可以再外部其它类中,可以直接建立内部类对象。
格式:外部类名.内部类名 变量名=外部类对象.内部类对象;
如:Outer.Inner in=new Outer().new Inner();
2当内部类在成员位置上,就可以被成员修饰符所修饰,比如:private,将内部类在外部类中进行封装。还有static,内部类就具备static的特性。
当内部类被static修饰后,只能直接访问内部类中的static成员,出现了访问权限。
在外部其它类中,如何直接访问静态内部类呢?
方式:new 外部类名.内部类().函数名(参数);如:new Outer.Inner().Function();

如果内部类的成员函数也是静态的,访问方式是:Outer.Inner.Function();

注意:当内部类中定义了静态成员,该内部类必须是静态的。
当外部类中的静态方法访问内部类时,内部类也必须是静态的。

11内部类定义原则

当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事务在使用外部事物的内容。

12匿名内部类

在成员方法中也可以定义局部类,但该局部类不能被privatestatic修饰

内部类定义在局部时,不可以被成员修饰符修饰,可以直接访问外部类中的成员,因为还有外部类中的引用,但是不可以访问他所在的局部中的变量,只能访问final修饰的局部变量。

匿名内部类:
1.匿名内部类其实就是内部类的简写格式。就是没名字的内部类。
2.定义匿名内部类的前提:内部类必须继承一个类,或者实现接口。
3.匿名内部类的格式:new 父类或者接口(){定义子类的内容}
4.其实匿名内部类就是一个匿名子类对象,而且这个对象有点胖,可以理解为带内容的内部对象。
在成员方法中定义匿名内部类的方法:
public void 成员方法()
{
 new 外部接口或类名()
  {
   重写或覆盖外部类或接口中的方法或抽象方法;
  }.重写或自己特有的方法或覆盖的方法名();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值