黑马程序员-----java基础面之面向对象(3)

时间:2023-02-14 12:34:23

黑马程序员-----java基础面之面向对象(3)

                                     ------- android培训java培训、期待与您交流! ----------

 

方向不对,努力白费!

每天静坐十分钟, 静坐的好处:1,消除负能量 2,吸收正能量。

      多态(重点)

多态: 多种状态,多种形态

多态的前提:1.有存在继承关系  2.要有重写

 

多态的优点:

                   1.提高了程序前期的扩展性

                   2.提高了程序后其的可维护性.

 

多态伪代码:

         class宠物{

                       void 叫(){

                       }

                   }

 

                   class狗 extends 宠物{

                            void 叫(){

                                     system.out.println(“汪汪-----”);

}

                   }

 

                   class猫 extends 宠物{

                            void叫(){

         system.out.println(“喵喵-------”);

}

                   }

                   ClassDemo (){

                            Publicstatic void main(String[] args){

//父类引用指向子类对象

                                     宠物  cw=new 狗();

宠物  cw=new 猫();

 

}

}

 

多态存在时,成员属性与成员方法表现

 

class Father{

         Stringname="tom"; //实例属性

         staticString country="zh"; //类属性

                   //实例方法

                   publicvoid show(){                    

                            System.out.println("father类中的show");

                   }

                   //类方法

                   publicstatic void method(){

                            System.out.println("father类中的静态方法");

                   }

}

 

class Son extends Father{

         Stringname="tony"; //将从父类中的继承的name属性隐藏了.   实例属性

static Stringcountry="china"; //类属性

                   //子类中重写的方法  实例方法

         publicvoid show(){                    

                   System.out.println("son类中的show");

         }

         //子类重写父类中的静态方法

         publicstatic void method(){

                   System.out.println("son类中的静态方法");

         }

}

                  

                   Fathera=new Son();

                           

                   1.实例属性  a.name

                            编译时:查看Father中是否存在name属性

                            执行时:调用的是Father中的name属性

 

                   2.类属性   a.country

                            编译时:查看Father中是否存在country属性

                            执行时:调用的是Father中的country属性

                  

                  

 

                   3.类方法  a.method();

                            编译时:查看Father中是否存在method()静态方法

                            执行时:调用的是Father中的method()静态方法       

 

                  

                   4.实例方法  a.show();

 

                            编译时:查看Father中是否存在show()实例方法

                            执行时:执行的是子类Son中的show()实例方法。

 

 

                   结论:1.关于属性都是查看父类中是否存在该属性,调用的也是父类中的属性静态方法也是一样的。

                        2.对于实例方法来说编译时查看父类中是否有这个方法,真正执行时执行的是子类中的重写方法。

             

      多态的弊端

程序有好处肯定也有弊端, 来看看多态的弊端是什么.

 

父类引用指向子类对象时,缺点就是不能调用子类中所特有的成员                    

多态存在时类型的转换

                  

                   前提:必须存在多态

 

                   自动转换(向上转型) :父类引用指向子类对象  Father f=new Son();

                   强制转换(向下转型): Sonson=(Son)f;

 

                   在做向下转型时会使用到一个  instanceof 关系操作符

                   它的作用是判断某个引用所指向的对象的类型是否是指定的类型

                   格式    引用(对象)  instanceof 类型

                   它操作后得到的结果是一个boolean类型的值。

                   instanceof只能判断有关系的操作。

                   使用instanceof会有一个问题,如果判断的是父类类型,它返回的也是true.

                   如果真正要判断一个引用所指向的对象的真实类型  通过getClass()方法去获得.

 

         多态小练习:

                            简单计算器操作

                            关于计算器我们提供了 加 减 乘  除class Test3

                                     {

                                               publicstatic void main(String[] args)

                                               {

                                                        inta=10;

                                                        intb=5;

 

                                                        char[]ch={'+','-','*','/'};

                                                        charc=ch[0];

                                                       

         //我们现在要求a,b这两个数做c操作后的结果.那么我们就需要一个运算类对象

                                                       

Operationop=OperationFactory.getInstance('+'); //Operation op=new Add();

int result=op.oper(a,b);

//父类引用指向子类对象调用实例方法时,调用的是子类中重写的方法。

 

                                                        System.out.println(""+a+c+b+"="+result);

                                               }

                                     }

                                     //这是一个运算的工厂类,它的作用是可以生产运算对象

                                     classOperationFactory

                                     {

                   //生产运算对象的方法,这个方法是根据传递的符号来判断生产哪一个对象.

                                               /*

                                                        参数: charc  判断的符号

                                                        返回值:Operation对象

                                               */

 

                                               publicstatic Operation getInstance(char c){

                                                        Operationop=null;

                                                        switch(c){

                                                                 case'+':op=new Add();break;

                                                                 case'-':op=new Sub();break;

                                                                 case'*':op=new Mul();break;

                                                                 case'/':op=new Div();break;

                                                        }

                                                        returnop;  //new Add();

                                               }

                                     }

 

                                     //运算类

                                     classOperation

                                     {       

                                               //计算行为

                                               intoper(int a,int b){

                                                        return0; //存在的一个弊端.

                                               }

                                     }

 

 

                                     //加法类

                                     classAdd  extends Operation{

                                                        //计算行为

                                                        int  oper(int a,int b){

                                                                 returna+b;

                                                        }

                                     }

                                     //减法

                                     classSub extends Operation{

                                                        //计算行为

                                                        intoper(int a,int b){

                                                                 returna-b;

                                                        }

                                     }

 

                                     //除法类

                                     classDiv extends Operation{

                                                        //计算行为

                                                        int  oper(int a,int b){

                                                                 returna/b;  //除数不能为0 这也是一个弊端

                                                                 }

                                     }

 

                                     //乘法

                                     classMul extends Operation{

                                               //计算行为

                                               intoper(int a,int b){

                                                        returna*b;

                                               }

                                     }

抽象类

 

抽象类也是一个类,也存在多态

 

抽象类:

                   使用abstract修饰的类就是抽象类.

 

                   abstractclass A{  //抽象类

                   }

 

抽象方法:

                  

                   使用abstract修饰的方法就是抽象方法,抽象方法只有方法的声明,而没有方法的实现.

 

                   abstractclass A{

                           

                            abstractvoid show(); //对于抽象方法来说,它只有方法的声明,而没有方法的实现。

                   }

抽象类与抽象方法的特点

1.抽象类不能被实例化不能new

                   2.抽象类是用来被子类继承的。

                   3.抽象类中可以有抽象方法。(抽象方法必须存在于抽象类中)

                   4.对于包含抽象方法的抽象类,子类必须将其中的所有抽象方法重写.

 

抽象类详解:

 

1.抽象类中没有抽象属性这个概念

 

                   2.抽象类中的构造方法

                            1.抽象类中是否有构造方法? 

                                     有

                            2.抽象类中的构造方法有什么有?

                                     帮助子类进行实例化

 

                   3.如果父子都是抽象类那么有什么情况?

                            子类可以对父类中的抽象方法进行选择性重写。

                   4.如果父类是一个普通类,子类是一个抽象类

                            可以

                  

                   5.抽象关键字abstract不可以和哪些关键字共存?

                           

                            修饰类  final

                            修饰方法  private static   final

 

                            final是否可以与abstract共存?

                                     不能共存

                                     final修饰类代表这个类不能被继承 而abstract的类必须被继承

                                     final修饰方法代表这个方法不能被重写 而abstract方法必须被重写

 

                            abstract是否可以与static共存吗?

                                     static方法可以通过类名直接调用,但是abstract方法没有实体

                           

                            private是否可以与abstract共存吗?

                                     不行

                   6.抽象类中的抽象方法是否可以不是抽象?

                            1.全是抽象  

                            2.全不是抽象  行  适配器 

                            3.混合到一起  行  模板方法模式

模板方法模式

 

                            模板方法模式:它的作用

 

                                               它将要执行的动作的顺序进行限定,

                                               将其进行隐藏,这样提高了代码的安全性.

 

                           

                            现在规定连接数据库有三步

                                     1.进行连接

                                     2.进行操作

                                     3.关闭数据库

 

                            对于不同的数据库我们在连接时,与操作时,关闭时它细节性的内容不同。

 

                            abstractclass ConnectDb{

                                    

                                     abstractvoid connection();

                                     abstractvoid operation();

                                     abstractvoid close();

 

                                     //这个方法不是抽象的

                                     voidrun(){ //运行

                                               connection();

                                               operation();

                                               close();

                                     }

                            }

 

                            classOracleConnection extends ConnectionDb{

                                      void connection(){}

                                      void operation(){}

                                      void close(){}

                            }

 

接口

接口你可以理解成一个特殊的抽象类

看类的组成部分

                   class类名{

                            成员属性

                            成员方法

                   }

接口的组成

                   1.接口的声明   interface

 

                   interface接口名{

                           

                            属性  默认修饰符  public static final

                            方法  默认修饰符  public abstract

                   }

 

                   接口中的成员的权限全是public

 

接口的作用:

1.      接口可以多实现

实现的关键字: implements

                            interfaceA{

                                     voida();

                            }

                            interfaceB{

                                     voidb();

                            }

                            classC implements A,B{

                                     publicvoid a(){}

                                     publicvoid b(){}

                            }

                            java中不能多继承,为什么可以多实现

                                     classA{

                                               voida(){} //实体方法

                                     }

                                     classB{

                                               voida(){} //实体方法

                                     }

                                     classC extends A,B{

                                               publicvoid a(){} //是重写A类还是B类区分不开.       

                                     }

                                    

                                     接口中不会出现混淆问题

                                     interfaceA{

                                               voida(); //只是方法声明

                                     }

                                     interfaceB{

                                               voida(); //只是方法声明

                                     }

                                     classC implements A,B{

                                               publicvoid a(){}

                                     }

                           

                   2.接口用来解耦合

                            解决类与类之间的问题

 

                   3.接口是程序功能的扩展

                            继承描述的是  is 关系  基本功能键

                            接口描述的是  like 扩展功能

                            //抽烟的人

                            interfaceSmokingPerson{

                            }

                            //打球的人

                            interfacePlayBall{

                            }

                            classPerson{

                                     voideat(){}

                                     voidrun(){}

                            }

 

                            classStudent extends Person implements PlayBall{

                                     voideat(){

                                     }

                                     voidrun(){

                                    

                                     }

                            }

 

                            classTeacher extends Person implements SmokingPerson

                            {

                                     voideat(){

                                    

                                     }

                                     voidrun(){

                                    

                                     }

                            }

                   4.对外暴露的规则

                           

                            接口强制性规定应该做什么

                   接口与类的关系 实现  implements

                            当一个类实现了某个接口,那么这个类必须将接口中所有方法重写.

                            因为接口中的方法都是抽象的。

                           

                   类与类之间关系 继承  extends

                   接口与接口之间也存在关系extends  子接口将父接口中的所有成员都继承.

                            interfaceA{

                                     voida();

                            }

                            interfaceD{

                                     voidd();

                            }

                            interfaceB extends A,D{

                                     voidb();

                            }

                            classC implements B{

                                     publicvoid b(){}

                                     publicvoid a(){}

                            }

 

         接口的思想    

                   其时就是一种公共的标准。

                   面向接口的编程

                   一般我们在说接口时有两种概念

                            1.java中的接口  interface

                            2.公共的标准.

                            API  应用程序接口

接口关系总结:

类与类   extends  只能单继承

                   类与接口  implements 可以多实现

                   接口与接口  extends 可以多继承

抽象类与接口的区别

                  

                   1.抽象类是一个类,它是用来被继承的,只能单继承

                     接口是用来被实现的,它可以多实现

 

                   2.抽象类描述的是is 它描述的是基本功能

                     接口描述的是like 它描述的扩展的功能

 

3.抽象类中可以有抽象方法也可以没有抽象方法

                     接口中的方法全是抽象的。

         接口也存在多态(接口回调),但是接口中的成员全是虚拟的概念,它没有构造方法.

         为什么没有,因为接口中的属性全是static

         多态的前提:1必须存在继承或实现  2.必须有重写

         在实际开发中,我们现在继承也可以,实现也可以。

         一般首选实现

Object类介绍

它是java中所有类的父类基类 根类 超类.

         在Object类中定义的方法,所有的类中都有。

         学习一个类步骤:

                   1.查看当前类的声明 观看这个类修饰符特点  父类是谁  实现了什么接口.

                   2.查看这个类的说明

                   3.创建这个类的对象  观看其提供的构造方法

                   4.查看这个类的成员方法

                            点击超连接,可以查看当前这个方法的详细说明

 

Object类中的代表方法介绍

                  

                   1.toString

                            Object类中的toString 方法

                            声明  public String toString()

                            作用  对象字符串化

                            Object类中的toString方法返回的字符串是  类名+@+16进制的hash码值

                            在实际开发中toString方法怎样重写?

一般我们使用toString方法完成的是对象的属性显示

                   2.equals

                            声明 publicboolean equals(Object obj)

                             比较两个对象是否相等

                            Object类中的equals方法的实现与==是一样的,

它都是用来比较两个对象的地址值

                             对于同一个类的对象,如果属性相同,我们认为它们相等。

                             这个时候就可以对equals方法进行重写来判断

                            从Object类中继承的equals方法它比较的是对象的地址,与==操作是一样的

                            我们重写equals方法的目的,为了比较对象的属性是否相等。

                            如果对象的属性一样,我们让equals方法返回true。否则返回

                            false,这个时候的equals方法就是比较对象的内容.

 

                   3.hashCode              

                            当咱们讲集合时会说

                                     当我们重写equals方法时,需要将hashCode方法也重写.

                   4.clone  

                            声明 protectedObject clone();

                            作用:创建一个对象的副本

                            注意

                                     1.必须在被克隆类中重写clone方法

                                     2.必须让被克隆类实现cloneable接口

 

                   5.finalize

                            声明:protectedvoid finalize()

                 throws Throwable

                            作用:这个方法就是当垃圾回收机制执行时要执行的方法。

                                 这个方法一般我们不进行重写.

 

                   6.getClass

                            声明:publicfinal Class getClass()

                            这个方法的返回值是Class,它代表的是字节码文件对象.

                             对于Class类中我们需要知道一个方法  String getName()

                             作用就是获得字节码文件名字

内部类

内部类:在一个类中又声明了一个类.

伪代码:

class A{ //外部类

                           

                            classB{  //内部类

                           

                            }

                   }

内部类的作用

内部类一般是在分析阶段.

                   发现某一个实体是另外一个实体的不可分隔的部分

伪代码举例:

class 人{

                            class心脏{

                            }

                            class脑{

                            }

                   }

内部类的定义位置细节

1.      内部类可以声明在类的成员位置上,对于这种情况,

内部类是可以使用成员修饰符的。 private static

2.      内部类可以声明在方法内.

 

内部类声明在成员位置上

                            对于内部类来说它可以直接访问外部类的成员

                            a.应用的比较多的访问方式(建议访问方式)

                                     在外部类定义方法,去访问内部类的成员

                            b.在外部去直接访问内部类的成员

非static修饰的内部类, 外部类名.内部类名引用=new 外部类名().new 内部类名();

static修饰的内部类, 外部类名.内部类名 引用=new 外部类.内部类();

关于内部类声明在成员位置上时它的static修饰的问题

                  

                   1.如果内部类使用static修饰,在内部类中就不能直接访问外部类的非static成员

                   2.如果内部类中有static成员,内部类必须使用static修饰

                   3.如果内部类使用static修饰,那内部类的成员可以是static,也可以不是.

在实际开发内部类一般都会是使用private,这时候只能合适我们所说的第一种方式方法

                   如果是非private可以使用其它方式

 

内部类定义在局部位置(定义在方法内)

只能在局部位置创建内部类的对象去访问

         a.内部类可以直接外部类的成员

         b.内部类可以直接访问局部变量,局部变量必须使用final修饰

         c.内部类中如果出现与外部类同名的成员,

                   这个时候的this代表的是内部类对象,而要使用外部类

                  需要  外部类名.this 这个代表的是外部类的对象

 

举例:

//关于内部类定义在局部时访问局部变量

                                     classOuter{

                                               Stringname="tom1"; //外部类的成员

                                               publicvoid show(final String name){

                                                        //finalString name="tom";

                                                        classInner{

                                                                 Stringname="tom2"; //内部类的成员

                                                                 publicvoid print(){

                                                                           Stringname="tom3"; //局部变量

                                                                           System.out.println(name);

                                                                           System.out.println(this.name);

                                                                           System.out.println(Outer.this.name);

                                                                 }

                                                        }

                                               }

                                     }

内部类产生的.class文件特点

                  

                   在成员位置   外部类名$内部类名.class

                   在局部位置   外部类名$序号内部类名.class

匿名内部类

内部类的一种简化写法,图形化界面时会比较常用

格式

                   new类名|接口名([参数]){

                            //属性-------->很少使用

                            //方法-------->可以是自定义方法但是绝大多数情况下都是重写的方法。

                   };

                   new代表创建一个匿名内部类对象

                   类名|接口名  代表的是匿名内部类继承的父类或实现的接口

                   {}它代表的是匿名内部类的内容

 

小笔试题:

 

Object obj=new Object(){

                            publicvoid show(){

                                     System.out.println("show....");

                            }

                   };

                   obj.show();//父类引用指向子类对象不能调用子类特有的方法

                   newObject(){

                           

                            publicvoid show(){

                                     System.out.println("show....");

                            }

                   }.show();//子类对象调用自己的方法

 

         我们在实际开发中,使用匿名内部类在局部位置上的时候比较多,

         并且一般都是将其做为一个参数进行传递.

                                               ------- android培训java培训、期待与您交流! ----------