面向对象(二)

3.9抽象类

1、特点

⑴、被abstract修饰的,只有声明没有实现的方法就是抽象方法,抽象方法必须被定义在抽象类中,该类也得被abstract修饰。

⑵、抽象类不可以实例化,因为调用方法没有意义。

⑶、抽象类的子类必须覆盖其所有的抽象方法后,该子类才可以实例化,否则该类还是抽象类。

2、问题细节

⑴、抽象类中有构造方法,用于给子类对象进行初始化

⑵、抽象类中也有非抽象方法,目的就是不让该类创建对象

3、抽象类不可以与那些关键字共存?

 ⑴、private:如果私有了,就不可以被子类覆盖了

⑵、static:

⑶、final:final是最终的,被他修饰的不可以覆盖。

4、抽象类与一般类的异同点:

⑴、相同:他们都是用来描述事物的,都在内部定义成员

⑵、不同:①、一般类有足够的信息描述事物,而抽象类信息不足

②、抽象类可定义抽象方法和非抽象方法,而一般类只能定义非抽象方法

③、抽象类不可以实例化,而一般类可以。

5、抽象类一定是父类,因为需要子类覆盖其所有的抽象方法后,才能对子类实例化。

abstractclass Employee {

    privateString name;

    privateString id;

    privatedoublepay;

    Employee(String name, String id, double pay) {

        this.name = name; 

        this.id = id;

        this.pay = pay;

    }

    publicabstractvoidwork();

}

class Manager extends Employee{

    privateintbonus;

    Manager(String name, String id, double pay, int bonus) {

        super(name,id,pay);

        this.bonus = bonus;

    }

    @Override

    publicvoid work() {

        Sop("Manager work");

    }

}

class Pro extends Employee{

    Pro(String name, String id, double pay) {

        super(name,id,pay);

    }

    @Override

    publicvoid work() {

        Sop("Pro work");

    }

}

publicclass AboutAbstract {

    publicstaticvoidmain(String[] args) {

        Manager man = new Manager("hufei", "4556",11110, 256);

        man.work();

    }

}

3.10接口

1、接口中常见的成员:全局常量和抽象方法

    注意:接口中的成员都是公共的,修饰符都是可以省略,但不建议,因为那样阅读性差。

2、实现:类与接口之间的关系(implements)

    接口是不可实例化的,只能由子类覆盖接口中的所有抽象方法后,子类才可以实例化

3、多实现

    ⑴、出现的原因:java中不支持多继承,于是改良成多实现,接口的出现避免了单继承的局限性

    ⑵、一个类中可以实现多个接口,因为接口中都是抽象方法,都没有方法体

    ⑶、实现与实现之间的关系:可以多继承,因为接口中都是抽象方法,都没有方法体。

    ⑷、一个类在继承另一个类的同时,还可以实现多个接口

4、特点:

    ⑴、接口是对外暴露的规则

    ⑵、接口是程序的功能扩展

    ⑶)、接口的出现降低了耦合性(紧密联系程度)

    ⑷、接口可以用来多实现

5、接口与抽象类的异同点

    ⑴、相同点:都是不断向上抽取而来的

    ⑵、不同点:①、前者需要被实现,而且可以多实现;后者需要被继承,但只能当单继承。

       ②、前者只能定义抽象方法,必须由子类去实现;后者可以定义抽象与非抽象类方法,子类继承后,可以直接使用非抽象方法。

       ③、前者在定义体系外的功能扩展;后者可以定义体系的基本共性内容

6、代码示例

abstractclass Student{

      abstractvoidstudy();

void sleep(){

          Sop("sleep");

     }

}

interface Smoke{

      publicabstractvoid smoking();

}

class Zhangsan extends Student implements Smoke{

       publicvoidsmoking() {}//实现抽烟接口

       @Override

   voidstudy() {}//复写study方法;

}

publicclass AboutInterface {

        publicstaticvoid main(String[] args) {

            Zhangsan zs = new Zhangsan();

            zs.sleep();

         }

}                                                      

3.11 多态

1、多态的体现:父类的引用指向了自己的子类对象,

2、好处:大大提高程序的扩展性

3、前提:必须有关系:继承,接口.必须存在覆盖

4、弊端:虽提高了扩展性,但是只能使用父类的引用访问父类中的成员

5、多态的应用

6、多态时,成员的特点

    ⑴、成员方法:在编译时,参阅引用型变量中所属的类中的是否存在能调用的方法,有,编译通过,否则,失败。在运行时,参阅对象所属的类中是否有调用的方法

    简单总结:成员方法在多态调用时,编译看左边,运行看右边

  以下注意面试题

⑵、成员变量:无论编译,还是运行都参考引用型变量中所属的类中的是否有调用的成员变量,有,编译通过,否则,失败。即左边           

    ⑶、静态方法:无论编译,还是运行都参考左边,从某种意义上讲,不涉及多态。

 7、代码示例

abstractclass Animal{

    abstractvoid eat();

}

class Cat extends Animal{

    void catchMouse(){

        Sop("抓老鼠");

    }

    voideat() {

        Sop("吃鱼");

    }  

}

class Dog extends Animal{

    voidwatchHome(){

        Sop("看家");

    }

    voideat() {

        Sop("吃骨头");

    }  

}

class Pig extends Animal{

    voidwatchHome(){

        Sop("看家");

    }

    voideat() {

        Sop("饲料");

    }  

}

publicclass AboutPolymorphic {

    publicstaticvoidmain(String[] args) {

      /* Cat c = new Cat();

         c.eat();

         Dog d = new Dog();

         d.eat();

         Pig p = new Pig();

         //为了提高以上代码的复用性,于是将eat功能提取出来写成function方法

         function(c);

         function(d);

         function(p);

        //可是当我们要扩展功能,比如加个pig,这样的话有得写function功能,可是function方法都一样,为了提高代码的复用性

      */

      //一个事物的多种存在形态

      // Animal a = new Cat(); //类型提升,向上转型

      // c.eat();

      // Cat c = (Cat)a;

//如果想要调用猫的特有方法,强制将父类的引用,转换成子类类型,即向下转型

      /*注意:①千万不要出现这样的操作,就是将父类对象转换子类类型。

我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。

          ③多态自始至终都是子类对象在做着变化

      */

       //c.catchMouse();

      function(new Cat());

      function(new Dog());

      function(new Pig());

     }

    publicstaticvoidfunction(Animal a){

        a.eat();

        if(a instanceof Cat){

//类型判断:instanceof

        //作用:用于判断对象的具体类型,只能用于引用数据类型判断,以及在向下转型前用于健壮性的判断。

           Catc = (Cat)a;

           c.catchMouse();

        }elseif(a instanceof Dog){

           Dogd = (Dog)a;

           d.watchHome();

        }

    }

     /*public static void function(Cat c){

         c.eat();

     }

     public static void function(Dog d){

         d.eat();

     }

     public static void function(Pig p){

        p.eat();

     }*/

}

3.12 内部类

1、访问规则

⑴、内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类的成员,是因为内部类中持有了一个外部类的引用,其格式是外部类名.this,

    ⑵、外部类要访问内部类,必须建立内部类对象

2、直接访问内部类格式

⑴、当内部类在外部类的成员位置上,而且非私有,在外部其他类中,可以直接建立内部类对象,其格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象;

          Outer.Inner in = new Outer().new Inner();    

    ⑵、当内部类在成员位置上,就可以被成员修饰符修饰

       ①、private :将内部类在外部类中进行封装

       ②、static:内部类就具备static的特性,称之为静态内部类。当内部类被static修饰后,只能直接访问外部类中的static成员,出现访问局限

       a、在外部其他类中,如何直接访问static内部类的非静态成员?

 new Outer.Inner().function();

       b、在外部其他类中,如何直接访问static内部类的静态成员?

           Outer.Inner.function();

       c、当内部类中定义了静态成员,内部类必须是静态的

       d、当外部类中的静态方法访问内部类时,内部类也必须是静态的

3、内部类定义原则

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

4、局部内部类

⑴、不可以被成员修饰符修饰

 ⑵、可以直接访问外部类中的成员,因为还持有外部类中的引用,但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量。

5、匿名内部类

⑴、前提:内部类必须继承或实现一个外部类接口

    ⑵、格式:new 父类或者接口(){定义子类的内容}

    ⑶、其实匿名内部类就是一个匿名子类对象,可以理解为带内容对象

    ⑷、局限性:当匿名内部类中方法过多的话,会造成混乱,因此其中定义的方法最好不要超过3个。

    ⑸、应用:当方法参数时接口类型时,而且接口中只有不超过3个,可以用匿名内部类作为实际参数进行传递

   6、代码示例:

abstractclass AbsDemo{

    abstractvoid show();

}

class Outer{

     privatestaticintnum =4;

     /*匿名内部类

       class Inner2 extends AbsDemo{

          @Override

          void show() {

             Sop(num);

        }

     }

     public void function(){

        new Inner2.show();}

-------------------------------------------------------------------------

     以上的代码可以写成以下形式

     public void function(){

         new AbsDemo(){//new AbsDemo(){void show() Sop("num"+num);}是AbsDemo类的子类对象,因为只有子类才能复写父类AbsDemo的抽象方法,当方法有几个的时候,可以给其去个名字AbsDemo a = newAbsDemo();

            @Override

            void show() {

                Sop("num"+num);

            }.show();   

         }*/

     class Inner{//当类是内部类时,就变成了外部类的成员了,所以可以被private修饰。

     //static class Inner{加静态的情况

        void function(){//非静态的情况

            //static void function(){加静态的情况

            int num = 6;

            Sop("innner:"+/*Outer.this.*/num);

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

        }

    }

    voidmethod(){

        finalint x= 56;

        class PartInner{ //局部内部类      

            void function(){

            Sop(Outer.this.num);

        }}

        new PartInner().function();

        /*Inner in = new Inner();//外部类要访问内部类,必须建立内部类对象

        in.function();*/

        }

}

publicclass InnerClass {

    publicstaticvoidmain(String[] args){

        //new Outer.Inner().function();访问static内部类的非静态成员的方式

        //Outer.Inner.function();访问static内部类的静态成员的方式

        Outer out = new Outer();

        out.method();

        //直接访问内部类中的成员

        Outer.Inner in = new Outer().new Inner();

    }

}

                                           目标四:2013/10/14 6:27

目标五(复习前面所有内容):2013/10/15 7:24

3.13 模板方法模式

1、原理:在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定部分,那么这时就将不确定的部分暴露出去,由该类子类去完成。
2
、例题:

(1)、需求:获取某一段程序运行的时间。
(2)
、原理:获取程序开始和结束的时间并相减即可。

(3)、代码示例:

abstractclass GetTime{//确定的代码依然放在这个方法中,只有不确定的runCode被覆写

  publicfinalvoidgetTime(){//利用final防止复写getTime方法

      long start = System.currentTimeMillis();//获取当前时间

      runCode();

      long end = System.currentTimeMillis();

      Sop("毫秒"+(end-start));

  }

  publicabstractvoidrunCode();//方法体不确定,所以抽象

}

class SubTime extends GetTime{

@Override

  publicvoid runCode() {//由于for循环代码在本例中i的值不确定,所以将其复写

      for (int i = 0; i < 1000; i++) {

          Sop(i);

  } } }

publicclass TemplateMethodPattern {

  publicstaticvoidmain(String[] args) {

      SubTime gt = new SubTime();

      gt.getTime();

       //Sop("毫秒"+gt);

}}

3.14

3.14.1Java中常用的包

1、java.lang:包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。

2、java.awt:包含了构成抽象窗口工具集(abstract windowtoolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。

3、java.net:包含执行与网络相关的操作的类。

4、java.io:包含能提供多种输入/输出功能的类。

5、java.util:包含一些实用工具类,如定义系统特性、使用与日期日历相关的方法。

3.14.2定义带包类

1、使用package语句加上包名来定义类所属于的包,包名全部小写

2、package语句为Java源文件的第一条语句

3、如果一个类中没有使用package语句,这个类为缺省无包名

4、一个类如果想被其他包中的类引用,必须使用public关键字修饰。构造方法也需要public,如果一个类被声明为public,那么必须和文件名同名

3.14.3使用带包的类

1、在使用带包的类时需要使用全限定名(包名.类名)

     全限定名有绝对路径的意思,比如一个文件file的存放路径,其绝对路径可能是/usr/local/sbin/file;这个名词也用在其他地方,比如Java类包的定名:com. linux.struct.sort.bubblesort,从最原始最上层的地方援引到具体的对象,这就是全限定名了。

2、在每次写类名时都使用全限定名很麻烦,我们可以使用import导入包,之后再使用就无需写包名了星号*:导入一个包中所有类。优先匹配当前包中的类,如果当前包没有再匹配导入包中的类,具体类名:导入指定一个类。无论当前包中是否有同名类,都直接匹配导入的类。

3、无包的类可以使用有包的类,有包的类不能使用无包的类。

3.14.4编译运行带包的类

1、编译一个带包的源文件,在生成class文件的同时需要生成包文件

编译命令:javac –d <目录> 源文件名.java

2、运行有包的类时需要加上包名

运行命令:java 包名.类名  

3.15 jar文件

3.15.1什么是jar文件

1、jar文件是Java文件的一种压缩格式

2、一般来讲,我们会将一个软件系统的所有class文件打成一个jar文件以供别人使用

3、当我们用到jar包中的类时,需要将jar文件的绝对路径加到classpath当中

3.15.2如何压缩jar文件

1、将编译好的带包的class文件压缩成一个jar文件称为打jar

2、打jar命令:jar  cvf  jar包名.jar 要打包的文件/文件夹

3、运行jar文件命令: java -jar jar文件名.jar

3.16访问控制符

1、类的访问控制符有两种

⑴、public关键字修饰:可以被所有的类访问

⑵、缺省为default:只能被同一包中的类访问

2、成员变量和方法访问控制符:

下面哪一种修饰词能使一个类中的成员变量仅仅具有包可见性:

A、protected

B、public

C、private

D、以上皆不对

3.17代码编写规范

1、标识符命名规则(驼峰式)

⑴、类名首字母大写:XxxYyyZzz

⑵、变量名、方法名首字母小写:xxxYyyZzz

⑶、包名全小写:xxx.yyy.zzz

⑷、常量名全大写:XXX_YYY_ZZZ

2、大括号的位置

⑴、大括号应成对出现,第一个大括号应在第一行语句后面

⑵、方法后面紧跟大括号,没有空格

⑶、关键字(while、for、if)后面应留一个空格

3、赋值语句之间用分号分隔,分号后面应空一格  

4、代码折行应按照代码等级对齐,运算符写在下一行

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值