黑马程序员java学习日记——面向对象(三)

来源:互联网 发布:直播摄像头美颜软件 编辑:程序博客网 时间:2024/05/21 19:33

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

一、     抽象类

 (1)抽象:把多个类中的共性的内容进行抽取,抽取后就能形成一个继承体系。但是,在今天的案例中,方法的声明相同,方法体不同,这样的抽取后,在父类中定义的时候,是不能写方法体的,这样的方法要想被java识别,就必须被标记为抽象的。如果一个类有抽象方法,那么该类肯定是抽象类。反之,抽象类中不一定有抽象方法。

    抽象类的由来:

多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。

例如:狼和狗都有吼叫的方法,可是吼叫内容是不一样的。所以抽象出来的犬科虽然有吼叫功能,但是并不明确吼叫的细节。

(2)格式:

   抽象方法只有方法声明,没有方法体,定义在抽象类中。

    格式:修饰符 abstract返回值类型 函数名(参数列表);

(2)好处:

      A:抽象类中可以有成员变量和非抽象方法,也可以实现代码的复用。

      B:抽象类强制要求继承他的子类必须完成某些功能。

   (3)成员特点:

      A:构造方法

          抽象类有构造方法,但是本身不能被实例化。

          它的构造方法用于子类实例化使用。

      B:成员变量

          抽象类既可以有成员变量,也可以有成员常量。

      C:成员方法

          抽象类既可以抽象方法,也可以有非抽象方法。

    代码示例:

abstract class Animal{private String name;public final int x = 10;public Animal(){System.out.println("animal");}public Animal(String name){this.name = name;}public void setName(String name){this.name = name;}public String getName(){return name;}public void show(){System.out.println("今天天气不错,适合学习");}public abstract void method();//定义抽象方法}class Dog extends Animal{public Dog(){super();System.out.println("dog");}public Dog(String name){super(name);}public void show(){System.out.println("今天天气不错,适合郊游");}public void method(){System.out.println("dog method");}}class AbstractDemo2 {public static void main(String[] args) {//创建对象//Animal a = new Animal();Dog d = new Dog();System.out.println(d.getName());Dog d2 = new Dog("小白");System.out.println(d2.getName());d2.show();d2.method();}}

(4)使用:

      当一个类继承一个抽象类的时候

          要么重写抽象类的所有抽象方法。

          要么本身是一个抽象类。

   (5)抽象类的注意事项

      A:抽象类没有构造方法,那么有什么用?

          有,用于子类实例化使用。

      B:是否有非抽象方法?如果没有抽象方法类为什么要定义为抽象类?

          有,提高代码复用性。

          没有抽象方法的抽象类就是为了不让他能创建对象。

      C:abstract不能和哪些关键系并存。

          private:私有的功能,子类是不能重写的。而abstract是要求子类重写的。

          fianl:最终的意思,子类不能重写。而abstract是要求子类重写的。

          static:静态的意思,它是跟类相关的。而我们研究的是对象间的关系。

                静态的东西,可以通过类名调用,但是,抽象的方法,用类名调用没有实际意义。

      修饰关键字:

          默认修饰符,private,public --成员变量private,成员方法public

          fianl:最终的,可以修饰类,成员变量,成员方法

          static:让成员多了一种调用方式。可以修饰成员。

          abstract:修饰类,修饰方法,表示是抽象。

          组合使用:

          一般格式:

             权限修饰符+static+final+成员变量/方法

      代码示例:

/*老师示例具体事物:基础班老师,就业班老师共性:姓名,年龄,讲课。根据我们学过的面向对象知识,我们就可以如下分析:定义一个老师类,然后,分别让基础班老师和就业班老师继承老师类。如何定义一个老师类呢,就是分析基础班老师和就业班老师的共性内容:老师类:成员变量:姓名,年龄成员方法:讲课 因为每个老师讲课的内容不一样,所以,我们定义为抽象方法。基础班老师:重写讲课方法输出老师的信息。就业班老师:重写讲课方法输出老师的信息。*/abstract class Teacher{private String name;private int age;public Teacher(){}public Teacher(String name,int age){this.name = name;this.age = age;}public String getName(){return name;}public int getAge(){return age;}//抽象的讲课方法public abstract void teach();public void printMessage(){System.out.println(name+"***"+age);}}class BaseTeacher extends Teacher{public BaseTeacher(String name,int age){super(name,age);}public void teach(){System.out.println("基础班老师讲JavaSE");}/*public void printMessage(){System.out.println(getName()+"***"+getAge());}*/}class WorkTeacher extends Teacher{public WorkTeacher(String name,int age){super(name,age);}public void teach(){System.out.println("就业班老师讲JavaEE");}}class TeacherDemo {public static void main(String[] args) {BaseTeacher bt = new BaseTeacher("林青霞",25);bt.teach();bt.printMessage();WorkTeacher wt = new WorkTeacher("郭德纲",38);wt.teach();wt.printMessage();//使用多态Teacher t = new BaseTeacher("刘姐",18);t.teach();t.printMessage();t = new WorkTeacher("芙蓉姐姐",20);t.teach();t.printMessage();}}

二、接口

 (1)接口:当一个抽象类中的方法都是抽象的时候,(并且都是成员常量的时候的。)java提供了一个新的表示形式,那就是接口。

(2)好处:

      A:接口是对外暴露的规则(比如:USB,电脑内部的插槽,CPU的针孔)

      B:接口是功能的扩展

      C:接口降低了程序的耦合性

          低耦合:类与类之间的关系

          高内聚:类本身的能力

      D:接口可以用来多实现

      E:类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口

      F:接口与接口之间可以有继承关系

(3)成员特点:

      A:成员变量

          成员变量都是常量,因为有默认修饰符:public static final

      B:成员方法

          成员方法都是抽象的,因为有默认修饰符:public abstract

      建议,每次自己写接口的时候,尽量把修饰符自己写上。

(4),接口相互间的关系:

      A:类与类

          继承关系,java只支持类的单继承,但是可以多重()继承。

      B:类与接口

          实现关系,可以单实现,也可以多实现。

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

      C:接口与接口

          继承关系,可以单继承,也可以多继承。

          如果一个类实现一个接口,就必须实现该接口及其父接口的所有抽象方法。

      代码示例:

interface Inter//定义一个接口{public abstract void show();//方法是抽象的}interface Inter2//定义第二个接口,两个方法都是抽象的{public abstract void method();public abstract void show();}interface Inter3 extends Inter,Inter2//第三个接口继承了前两个接口{public abstract void function();}class Fu //默认有个extends Object{}class Demo extends Fu implements Inter,Inter2//继承Fu类并实现了前两个接口{public void show()//复写show方法{System.out.println("demo show");}public void method()//复写method方法{System.out.println("demo method");}}

三、抽象类和接口的区别:

   (A)成员区别:

      抽象类:

          构造方法

          成员变量:可以是变量,也可以是常量。

          成员方法:可以是抽象方法,也可以是非抽象方法。

      接口:

          成员变量:只能是常量。默认修饰符:public static final

          成员方法:只能是抽象方法。默认修饰符:public abstract

   (2)类只能单继承

      而接口可以多继承。接口的出现避免了java的单继承的局限性。

   (3)抽象类被继承,类中定义的是继承体系的共性内容。

      接口被实现,接口中定义的是体系的扩展内容。

   (4)设计理解不同:

      抽象类被继承,体现的是一种:"is a"的关系

      接口被实现,体现的是一种:"like a"的关系

代码示例:

abstract class Person//抽象类{private String name;private int age;public void setName(String name){this.name = name;}public String getName(){return name;}public void setAge(int age){this.age = age;}public int getAge(){return age;}public abstract void eat();//定义抽象方法}abstract class Player extends Person{public abstract void study();//抽象方法 }abstract class Coach extends Person{public abstract void teach();//抽象方法}interface StudyEnglish//接口{public abstract void studyEnglish();//接口中的抽象方法}class PingPongStu extends Player implements StudyEnglish{public void studyEnglish()//复写抽象方法{System.out.println("乒乓运动员学英语");}public void study()//复写抽象方法{System.out.println("乒乓运动员学习乒乓");}public void eat()//复写抽象方法{System.out.println("乒乓运动员吃乒乓");}}class PingPongCoach extends Coach implements StudyEnglish{public void studyEnglish()//复写抽象方法{System.out.println("乒乓教练学英语");}public void teach()//复写抽象方法{System.out.println("乒乓教练教学员学乒乓");}public void eat()//复写抽象方法{System.out.println("乒乓教练吃乒乓乒乓");}}class BasketStu extends Player {public void study()//复写抽象方法{System.out.println("篮球运动员学打篮球");}public void eat()//复写抽象方法{System.out.println("篮球运动员吃篮球");}}class BasketCoach extends Coach {public void teach()//复写抽象方法{System.out.println("篮球教练教学员学打篮球");}public void eat()//复写抽象方法{System.out.println("篮球教练吃篮球");}}class PersonDemo{public static void main(String[] args){PingPongStu pps = new PingPongStu();pps.setName("王浩");pps.setAge(44);System.out.println("姓名是:"+pps.getName()+",年龄是:"+pps.getAge());pps.study();pps.eat();pps.studyEnglish();System.out.println("************************");BasketStu bs = new BasketStu();bs.setName("姚明");bs.setAge(50);System.out.println("姓名是:"+bs.getName()+",年龄是:"+bs.getAge());bs.study();bs.eat();System.out.println("************************");PingPongCoach ppc = new PingPongCoach();ppc.setName("乒乓刘教练");ppc.setAge(36);System.out.println("姓名是:"+ppc.getName()+",年龄是:"+ppc.getAge());ppc.teach();ppc.eat();ppc.studyEnglish();System.out.println("************************");BasketCoach bc = new BasketCoach();bc.setName("篮球张教练");bc.setAge(25);System.out.println("姓名是:"+bc.getName()+",年龄是:"+bc.getAge());bc.teach();bc.eat();}}

四、Object类的使用

   Object:Object是类层次结构的根类。每个类都使用Object作为超类。

   Object类中我们要掌握的功能:

      A:public String toString()

          返回该对象的字符串表示。建议所有子类都重写此方法。

          如果没有重写,默认的结果是:

             getClass().getName() + '@' + Integer.toHexString(hashCode())

             类名@哈希值的十六进制

             public static String toHexString(int i):i按照十六进制的数据返回。

          为什么要重写呢?

             因为地址值的显示对我们来说,没有意义。

             为了让显示的效果有意义一些,重写此方法。

        代码示例:

class Student extends Object{private String name;public Student(){}public void setName(String name){this.name = name;}public String getName(){return name;}//重写方法public String toString(){//成员变量的组成:多个成员变量用,隔开。//"name:"+name+",age:"+age;return "name:"+name;}}class ObjectDemo{public static void main(String[] args){//创建对象Student s = new Student();s.setName("林青霞");//Student@3e0ebb//其实在用输出语句输出一个对象的名称的时候,其实是用对象调用了toString()方法而已。System.out.println(s);System.out.println(s.toString()); //类@十六进制的hashCode()//hashCode方法System.out.println(s.hashCode()); //4067003 -- intSystem.out.println(Integer.toHexString(4067003)); //3e0ebb}}B:public int hashCode()返回该对象的哈希码值。C:finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。D:Class getClass():反射的时候讲。返回的是该类的字节码文件对象的类文件。E:public boolean equals(Object obj)指示其他某个对象是否与此对象"相等"。            如果类没有重写equals方法,那么它比的还是地址值。       代码示例:   class Student{private String name;private int age;public Student(){}public Student(String name,int age){this.name = name;this.age = age;}//重写equals方法public boolean equals(Object obj)//重写的是Object类中的equals方法{//为了提高程序的效率if(this == obj){return true;}//为了提高程序健壮性if(!(obj instanceof Student)){return false;}Student s = (Student)obj; //向下转型//这个if语句可以使用三元运算符改进//下边equals是String类中重写Object类中equals之后的                return this.name.equals(s.name) && this.age == s.age;}}class Demo{}class ObjectDemo3 {public static void main(String[] args) {Student s1 = new Student("李建峰",18);Student s2 = new Student("李建峰",18);Student s3 = new Student("张学友",20);System.out.println(s1.equals(s2));System.out.println(s1.equals(s3));//自己跟自己比System.out.println(s1.equals(s1));Demo d = new Demo();//ClassCastExceptionSystem.out.println(s1.equals(d));}}

五、内部类

1、内部类定义:

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

2、访问特点:

   A:内部类可以直接访问外部类中的成员,包括私有成员

   B:外部类要访问内部类中的成员必须要建立内部类的对象

代码示例:

class Outer{private int num = 10;//成员内部类class Inner{public void show(){System.out.println("num:"+num);}}//成员方法public void method(){//创建对象Inner in = new Inner();in.show();}}class InnerDemo{public static void main(String[] args){//在外部使用Outer o = new Outer();o.method();//注意格式:外部类.内部类 名字 = 外部类对象.内部类对象Outer.Inner oi = new Outer().new Inner();oi.show();}}

3、内部类位置

   A:成员位置

         a:如果没有被private或者static修饰。

            外部类.内部类 名字 =外部类对象.内部类对象;

            举例:

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

                oi.show();

         b:private或者static修饰。

            如果被private修饰后,就不能再在除了外部类的其他类中使用。

            如果被static修饰,并且没有被private修饰,使用方式如下:

            外部类.内部类 名字 =外部类.内部类对象;

            举例:

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

                oi.show();

           代码示例:

/*内部类被静态修饰:*/class Outer{private static int num = 10;static class Inner{public void show(){System.out.println("show:"+num);}public static void method(){System.out.println("method:"+num);}}}class InnerDemo3 {public static void main(String[] args) {//Outer.Inner oi = new Outer().new Inner();Outer.Inner oi = new Outer.Inner();oi.show();oi.method();//静态的不想通过对象访问Outer.Inner.method();}}

内部类被private修饰:

/*    内部类被private修饰*/class Outer{private int num = 10;private class Inner{public void show(){System.out.println("num:"+num);}}public void method(){Inner in = new Inner();in.show();}}class InnerDemo2 {public static void main(String[] args) {//内部类被private修饰后就不能再被使用//Outer.Inner oi = new Outer().new Inner();Outer o = new Outer();o.method();}}

B:局部位置

         a:有名字

            按照普通的方式使用即可。

         b:没有名字,匿名内部类(掌握)

            格式:

                new 类或者接口()

                {

                   重写方法,或者自定义方法

                };

                其实这里的本质是一个子类匿名对象。

            前提:外部存在着一个类或者接口。

内部类定义在局部位置:

     在外部类的方法中定义一个类。   

   为什么局部内部类访问局部变量需要用final修饰呢?

     因为内部类在使用完毕后,可能在堆内存还存在呢,这个时候,它要的变量也要存在。

     如果没用final修饰,变量就会从栈中消失。

     final修饰的内容在哪里?

     方法区里面有一个常量区。它的生命周期你可以想象成和static一样。

代码示例:

class Outer{//private int num = 10;public void method(){final int num = 20;//局部位置class Inner{public void show(){System.out.println("show "+num);}}//创建对象Inner in = new Inner();in.show();}}class InnerDemo4 {public static void main(String[] args) {Outer o = new Outer();o.method();}}

什么时候使用匿名内部类呢?

通常在使用方法是接口类型参数,并该接口中的方法不超过三个时,可以将匿名内部类作为参数传递。

增强阅读性。

匿名内部类的使用:

interface Inter{public abstract void hello();public abstract void haha();}class Outer{private int num = 10;public void method(){/*class Inner//内部类形式{public void show(){System.out.println("num:"+num);}}Inner in = new Inner();in.show();*//*new Inter(){//匿名内部类public void hello(){System.out.println("hello");}};*///怎么调用呢?/*new Inter(){//匿名内部类调用方法public void hello(){System.out.println("hello");}}.hello();*//*new Inter(){public void hello(){System.out.println("hello");}public void haha(){System.out.println("haha");}}.hello();new Inter(){public void hello(){System.out.println("hello");}public void haha(){System.out.println("haha");}}.haha();*///假如只是实现了接口的方法,那么还可以这样用Inter in = new Inter(){public void hello(){System.out.println("hello");}public void haha(){System.out.println("haha");}};in.hello();in.haha();}}class NiMingInnerDemo {public static void main(String[] args) {Outer o = new Outer();o.method();}}











 

 

原创粉丝点击