黑马程序员—Java面向对象(抽象类、模板方法设计模式、接口、多态、内部类)

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

 

 

 

抽象类:abstract

抽象:不具体,看不明白。抽象类表象体现。

在不断抽取过程中,将共性内容中的方法声明抽取,但是方法不一样,没有抽取,这时抽取到的方法,并不具体,需要被指定关键字abstract所标示,声明为抽象方法。

 

/**

 * 当多个类中出现了相同功能,但是功能主体不同,这时可以进行向上抽取。这时只抽取功能的定义。而不抽取功能主体。

 *

 * 抽象类的特点:

 * 1.抽象方法一定在抽象类中。

 * 2.抽象方法和抽象类都必须被abstract关键字修饰。

 * 3.抽象类不能用new创建对象,因为调用抽象方法没有意义。

 * 4.抽象类中的抽象方法要被使用,必须由子类重写其所有的抽象方法后,建立子类对象调用。

 *   如果子类只重写了部分抽象方法,那么该子类还是一个抽象类。

 */

代码示例:

 

//定义一个抽象类Student1

abstractclass Student1 {

    //抽象方法study

    abstract void study();

}

//基础班类

classBaseStudent extends Student1 {

    //实现study方法的具体细节

    void study() {

       System.out.println("Basestudy");

    }

}

//加强班类

classAdvStudent extends Student1 {

    //实现加强班类的study方法的具体细节

    void study() {

       System.out.println("Advstudy");

    }

}

抽象类的细节:

1:抽象类中是否有构造函数?有,用于给子类对象进行初始化。

2:抽象类中是否可以定义非抽象方法?

   可以。其实,抽象类和一般类没有太大的区别,都是在描述事物,只不过抽象类在描述事物时,有些功能不具体。所以抽象类和一般类在定义上,都是需要定义属性和行为的。只不过,比一般类多了一个抽象函数。而且比一般类少了一个创建对象的部分。

3:抽象关键字abstract和哪些不可以共存?final ,  private , static

4:抽象类中可不可以不定义抽象方法?可以。抽象方法目的仅仅为了不让该类创建对象。

 

 

 

模板方法设计模式:

*什么是模板方法呢?

 * 在定义功能时,功能的一部分是确定的。但是有一部分是不确定的。而确定的部分在使用不确定的部分。

 * 那么这时就将不确定的部分暴露出去,由该类的子类去完成。

 */

代码示例:

//获取时间类

abstractclass GetTime {

    //获取runCode函数的运行时间方法

    public final void getTime() {

       long start = System.currentTimeMillis();

       //不确定的功能代码

       runCode();

      

       long end = System.currentTimeMillis();

       System.out.println("毫秒数:" + (end - start));

    }

    //不确定的方法runCode,需要由子类去实现

    public abstract void runCode();

}

 

//GetTime类的子类,该类需要实现runCode方法

classSubTime extends GetTime {

    //实现runCode方法的具体细节

    public void runCode() {

       for (int x = 0; x < 100000; x++) {

           System.out.println(x);

       }

    }

}

//模板测试类

publicclass TemplateDemo {

 

    public static void main(String[] args) {

       //创建子类的实例对象

       SubTime time = new SubTime();

       //调用getTime方法,打印结果

       time.getTime();

    }

}

 

 

接口:

/*接口:初期理解。可以认为是一个特殊的抽象类,当抽象类中的方法都是抽象方法时。那么该类可以通过接口的形式来表示。

 * class用于定义类,interface用于定义接口。

 *

 * 接口定义的格式特点:

 * 1.接口中常见的定义:常量、抽象方法。

 * 2.接口中的成员都有固定的修饰符。只要写上interface,就算没写这些固定修饰符,系统会默认自动加上的。

 *   常量 public static final

 *   方法public abstract

 * 记住:接口中的成员都是public修饰的。

 *

 * 接口是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都重写后才可以实例化。

 * 否则子类还是一个抽象类。

 *

 * 一个类可以同时实现多个接口。也是对多继承不支持的转换形式。java支持多实现。

其实java中是有多继承的。接口与接口之间存在着继承关系,接口可以多继承接口。

 *

 * 接口的好处: 1.对外暴露规则。

 *         2.提高了功能的扩展性。

 *         3.降低了耦合性。

 * */

 

代码示例:

//定义一个接口Inter

interfaceInter {

    //静态常量

    public static final int CHANG_LIANG_MING =23;

    //抽象方法show

    public abstract void show();

}

//定义一个接口InterA

interfaceInterA {

    //静态常量AGE

    public static final int AGE = 22;

    //抽象方法show

    public abstract void show();

    //抽象方法method

    public abstract void method();

}

//定义一个Demo1类

classDemo1 {

    public void function() {

      

    }

}

//定义一个Test类,继承了Demo1类,并且实现了Inter和InterA两个接口

classTest extends Demo1 implements Inter, InterA {

    //实现接口的show方法

    public void show() {

      

    }

    //实现接口的method方法

    public void method() {

      

    }

}

 

//接口A

interfaceA {

   

    public abstract void methodA();

}

//接口B继承接口A

interfaceB extends A {

   

    public abstract void methodB();

}

//interfaceC extends B, A {    接口与接口中可以实现多继承

//接口C继承接口B

interfaceC extends B {    

   

    public abstract void methodC();

}

//接口E继承C

classE implements C {

    //实现A接口的methodA方法

    public void methodA() {}

    //实现B接口的methodB方法

    public void methodB() {}

    //实现C接口的methodC方法

    public void methodC() {}

}

 

 

 

多态:

/*多态:理解为事物存在的多种体现形态。人:男人、女人    动物:猫、狗...

 * 猫 m = new 猫();   多态: 动物 m = new 猫();

 * 1.多态的体现。

 *   父类的引用指向自己子类的对象。父类的引用也可以接收自己子类的对象。

 *   Animal= new Dog();

 * 2.多态的前提。

 *   必须类与类之间有关系,要么继承,要么实现。还有一个前提:存在方法重写。

 *

 * 3.多态的好处。

 *   多态的出现大大的提高了程序的扩展性。

 *  

 * 4.多态的弊端。

 *   提高了扩展性,但是只能使用父类的引用访问父类中的成员。

 * * */

 

class 毕姥爷{

    void讲课(){

       System.out.println("企业管理");

    }

    void钓鱼(){

       System.out.println("钓鱼");

    }

}

class 毕老师 extends 毕姥爷{

    void讲课(){

       System.out.println("JAVA");

    }

    void看电影(){

       System.out.println("看电影");

    }

}

class {

    publicstatic void main(String[] args) {

       毕姥爷 x = new 毕老师(); //毕老师对象被提升为了毕姥爷类型。

//     x.讲课();

//     x.看电影();  //错误.

       毕老师 y = (毕老师)x; //将毕姥爷类型强制转换成毕老师类型。

       y.看电影();//在多态中,自始自终都是子类对象在做着类型的变化。

    }

}

如果想用子类对象的特有方法,如何判断对象是哪个具体的子类类型呢?

可以可以通过一个关键字 instanceof ;//判断对象是否实现了指定的接口或继承了指定的类

 

格式:<对象 instanceof类型>,判断一个对象是否所属于指定的类型。

Student instanceofPerson = true;//student继承了person类

 

在多态中,成员函数的特点:

 *  编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,则编译通过。如果没有,则编译失败。

 *  运行时期:参阅的是对象所属的类中是否有调用的方法。

 *  简单的总结就是:成员函数在多态调用时,编译看左边,运行看右边。

 * 

 *  多态中成员变量的特点:无论编译还是运行都是参考左边。

 * 

 * 多态中静态成员函数的特点:无论编译还是运行都是参考左边。

 

/*  Object:是所有对象的直接或者间接父类。传说中的上帝。

 *        该类中定义的是所有对象都具备的功能。

 *        

 *  如果自定义类中有比较相同的方法,没有必要重新定义。只要重写父类中的方法,建立自己特有的比较内容即可。

 * */

 

具体方法:

1,booleanequals(Object obj):用于比较两个对象是否相等,其实内部比较的就是两个对象地址。

而根据对象的属性不同,判断对象是否相同的具体内容也不一样。所以在定义类时,一般都会复写equals方法,建立本类特有的判断对象是否相同的依据。

publicboolean equals(Object obj) {    //Objectobj = new Demo();

       if (!(obj instanceof Demo))

           return false;

       Demo d = (Demo) obj;

       return this.age == d.age;

    }

2,StringtoString():将对象变成字符串;默认返回的格式:类名@哈希值 = getClass().getName() +'@' + Integer.toHexString(hashCode())

  为了对象对应的字符串内容有意义,可以通过复写,建立该类对象自己特有的字符串表现形式。

publicString toString() {

       return "Person age=" + age;

    }

 

3,inthashCode():返回该对象的哈希码值。支持此方法是为了提高哈希表的性能。

通常equalstoStringhashCode,在应用中都会被复写,建立具体对象的特有的内容。

 

 

 

内部类:

如果A类需要直接访问B类中的成员,而B类又需要建立A类的对象。这时,为了方便设计和访问,直接将A类定义在B类中。就可以了。A类就称为内部类。内部类可以直接访问外部类中的成员。而外部类想要访问内部类,必须要建立内部类的对象。

/*  一、内部类的访问规则:

 *     1.内部类可以直接访问外部内的成员,包括私有的。

 *       之所以内部类能直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式为  外部类名.this

 *     2.外部类要访问内部类,必须先建立内部类对象。

 *    

 *  二、访问格式:

 *     当内部类定义在外部类的成员位置上,而且非私有,可以在外部其它类中建立该内部类对象。

 *     格式为 外部类名.内部类名  内部类对象名   =   new外部类名().new内部类名();

 *            Outer.Inter in = new Outer().newInter();

 * 

 *  三、当内部类在成员位置上时,就可以被成员修饰符所修饰。

 *     如:private 将内部类在外部类中进行封装。

 *       static  内部类就具备了static的特性。

 *       当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。

 *       

 *     在外部其它类中如何访问static内部类里的非静态成员呢?

 *     new Outer.Inter().function();

 *     

 *     在外部其它类中如何访问static内部类里的静态成员呢?

 *     Outer.Inter.function();

 *     

 *     注意:当内部类中定义了静态成员,该内部类也必须是static的。

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

 *    

 *     当描述事物时,事物的内部还有事物,该事物就由内部类描述,因为内部类中的事物可以使用外部类中的事物的内容。

 *    class Body {

 *        

 *        private class Heart {

 *       

 *           void jump() {

 *           

 *           }

 *       }

 *       

 *       public void method() {

 *          

 *          new Heart().jump();

 *       }

 *     }

 * */

 

classOuter {

   

    int x = 3;

   

    static class Inter { //内部类

      

       int x = 5;

      

       public static void function() {

          

           int x = 8;

           System.out.println("InterClass="+ x);//打印8:x 打印5:this.x  打印3:Outer.this.x

       }

    }

   

    public void method() {

      

       System.out.println("OuterClass="+ x);

       Inter i = new Inter();

       i.function();

    }

}

 

publicclass InterClassDemo {

 

    public static void main(String[] args) {

      

       Outer o = new Outer();

//     o.method();

      

//     Outer.Inter in = new Outer().newInter();//1.建立非静态内部类对象。先创建外部类对象,再创建内部类对象

//     in.function();      

      

//     Outer o2 = new Outer();   //2.建立非静态内部类对象。先建立外部类对象,再通过外部类对象建立内部类对象。

//     Outer.Inter in2 = o2.new Inter();

 

      

       Outer.Inter in = new Outer.Inter(); //1.建立静态内部类对象,访问静态内部类格式。

       new Outer.Inter();                  //2.建立静态内部类的匿名对象。 

       new Outer.Inter().function();       //访问静态内部类中的非静态成员方法。

      

       Outer.Inter.function();  //访问静态内部类中的静态成员方法。

    }

}

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

你可能感兴趣的:(黑马程序员—Java面向对象(抽象类、模板方法设计模式、接口、多态、内部类))