码迷,mamicode.com
首页 > 编程语言 > 详细

java之面向对象(二)

时间:2015-03-08 16:59:23      阅读:288      评论:0      收藏:0      [点我收藏+]

标签:

主要知识点:

  1. Object类
  2. 单例模式
  3. final关键字
  4. 抽象类
  5. 接口
  6. 内部类

  • Object类

Object所有类的直接或者间接的父类,java认为所有的对象都具备一些基本的共性内容,这些内容可以不断的向上抽取,最终就抽取到了一个顶层的类中,该类中定义的就是所有对象都具备的功能。

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

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

public boolean equals(Object obj){
    if(!(obj instanceof Person))
        return false;
    Person p = (Person)obj;
        return this.age == p.age;
}        

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

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

public String toString(){
    return "person : "+age;
}

3.Class getClass():获取任意对象运行时的所属字节码文件。反射的时候详细说。

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

 


 

  • 单例模式

解决的问题:保证一个类在内存中的对象唯一性。

比如:多程序读取一个配置文件时,建议配置文件封装成对象。会方便操作其中的数据,又要保证多个程序读到的是同一个配置文件,就需要该配置文件对象在内存中是唯一的。

Runtime()方法就是单例模式进行设计的。

 

如何保证对象的唯一性呢?

思想:1.不让其他程序创建该类对象。2.在本类中创建一个本类对象。3.对外提供方法,让其他程序获取这个对象。

步骤:

  1. 因为创建对象都需要构造函数初始化,只要将本类中的构造函数私有化,其他程序就无法创建该类对象。
  2. 就在类中创建一个本类对象。
  3. 定义一个方法,返回该对象,让其他程序可以通过方法就得到本类对象。(作用:可控)

代码体现:

  1. 私有化构造函数
  2. 创建私有并静态的本类对象。
  3. 定义公有并静态的方法,返回该对象。
//饿汉式
class Single{
    private Single(){} // 私有化构造函数。
    private static Single s = new Single(); // 创建私有并静态的本类对象。
    public static Single getInstance(){ // 定义公有并静态的方法,返回该对象。
        return s;
    }
}

//懒汉式:延迟加载方式。
class Single2{
    private Single2(){}
    private static Single2 s = null;
    public static Single2 getInstance(){
        f(s==null)
            s = new Single2();
        return s;
    }
}    

 


  • final关键字
  1. final可以修饰类方法变量。
  2. final类不可以被继承,但是可以继承其他类。
  3. final修饰方法不可以被复写,但是可以复写父类方法。
  4. final修饰的变量称为常量,这些变量只能赋值一次。
  5. 内部类在局部时,只可以访问被final修饰的变量。
  6. final修饰的引用类型变量,表示该变量的引用不能变,而不是该变量的值不能变。

  • 抽象类

当描述事物时,没有足够的信息对事物进行描述,那么该描述对应的类就是一个抽象类。

狗:
    行为:吼叫
狼:
    行为:吼叫
狼和狗具备着共性功能,可以抽取,
它们都是犬科中的一种。而吼叫是犬科中的基本功能。

abstract class 犬科
{
    static abstract void 吼叫();
}

classextends 犬科
{
    void 吼叫()
    {
        System.out.println("汪汪");
    }
}
classextends 犬科
{
    void 吼叫()
    {
        System.out.println("嗷嗷");
    }
}

当我们编写一个类时,我们往往会为了该类定义一些方法,这些方法是为了描述该类的行为方式,那么这些方法都有具体的方法体。但是,有的时候父类只知道子类应该包含怎么样的方法,但是无法准确的知道子类如何实现该方法。这时就用到了抽象类。

 

抽象类的特点:

  1.抽象方法只能定义在抽象类中,抽象类和抽象方法必须要用abstract关键字修饰(可以描述类和方法,不可以描述变量)

  2.抽象方法只能定义方法声明,并不定义方法实现。

  3.抽象类不可以被创建对象。(实例化)。

  4.只有通过子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化,否则,该子类还是一个抽象类。

抽象类中的细节:

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

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

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

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

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

  5.一般类和抽象类有什么异同?

    相同之处:一般类和抽象类都是用于描述事物,里面都可以定义属性和行为,以及构造函数。

    不同之处:一般类中不可以定义抽象函数,抽象类可以。一般类可以实例化抽象类不行。

         一般类可以被继承,也可以不被继承,抽象类则一定要被继承,需要其子类覆盖所有的抽象方法子类才可以被实例化。

abstract方法:

  分析事物的时候,发现了共性的内容,就出现向上抽取,会有这样的一种特殊的情况,就是功能声明相同,但功能主体不同

  这时候也可以抽取,但是只抽取方法声明,不抽取方法主体,那么此方法就是一个抽象方法。

abstract class Person{
    abstract void show();
    abstract void inof();
    void turn(){
    }
}

class NewP extends Person{
    @Override
    void show() {
    }

    @Override
    void inof() {
    }
    //不覆写的话会报错
}

public class Demo {
    public static void main(String[] args) {
        //new Person();报错!因为抽象类不可以实例化
    }
}

 

抽象类的体现-模板模式:

解决的问题:当功能内部一部分实现时确定,一部分实现不确定,这时就可以把不确定的部分暴露出去,让子类去实现。

abstract class GetTime{
    public l final void getTime(){  // 此功能如果不需要复写,可加 l final  限定
        long start = System.currentTimeMillis();
        code();  // 不确定的功能部分,提取出来,通过抽象方法实现
        long end = System.currentTimeMillis();
       System.out.println("毫秒是:"+(end-start));
    }
    public abstract void code();  // 抽象不确定的功能,让子类复写实现
}
class SubDemo extends GetTime{
    public void  code(){  // 子类复写功能方法
        for(int y=0; y<1000; y++){
            System.out.println("y");
        }
    }
}                

 


  • 接口

引入:抽象类是从多个类中抽象出来的模板,若要将这种抽象进行的更彻底,就得用到一种特殊的”抽象类“ ---》接口

接口只定义了类应该遵循的规范,却不关心这些类的内部数据和其方法内的实现细节。

接口只规定了这些类里必须提供的方法,从而分离了规范和实现,增强了系统的可扩展性和可维护行。

举例:

 

技术分享

 

1.用关键字interface定义的。

2.接口中包含的成员,最常见的有全局常量,抽象方法,

  注意:接口的成员都有固定的修饰符。

  成员变量:public static final

  成员方法:public abstract

interface Inter{
    public static final int x = 3;   //public static final 都可以省略
    public abstract void show();    //public abstract 可以省略
}

3.接口中有抽象方法,说明接口不可以实例化,接口的子类必须实现接口的所有抽象方法后,该子类才可以实例化,否则,该子类还是抽象类。

4.类与类之间存在着继承关系,类与接口中间存在的是实现关系。

5.接口和类不一样的地方,就是,接口可以被多实现,这就是多继承改良的结果,java将多继承的机制通过多实现来体现。

6.一个类在继承另一个类的同时,还可以实现多个接口,所以接口的出现避免了单继承的局限性。还可以将类进行功能的拓展。

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

 

接口设计上的特点:

1.接口是对外提供的规则。

2.接口是功能的扩展

3.接口的出现降低了耦合性。

 

抽象类与接口:

抽象类:一般用于描述一个体系单元,将一组共性的内容进行抽取,可以在类中定义抽象内容让子类实现,也可以定义非抽象内容让子类直接使用,它里面都是体系的基本内容。

接口:一般用于定义对象的扩展功能,是在继承之外还需要这个对象具备的一些功能。

 

抽象类与接口的共性:都是不断向上抽取的结果。

抽象类和接口的区别:

1.抽象类只能被继承,而且只能单继承。接口需要被实现,而且可以多实现。

2.抽象类中可以定义非抽象方法,子类可以直接使用。

接口中都有抽象的方法,需要子类去实现。

3.抽象类使用的是 is a 的关系。

接口使用的是 like a 的关系。

4.抽象类的成员修饰符可以自定义。

接口中的成员修饰符是固定的,全部都是public。

 


  • 内部类

类是用于描述事物的,而事物中如果还有具体的事物,而且这个内部的事物在访问着所属事物的内容,这时这个内部的事物也需要用类来描述,这个类就是内部类。

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

 

特点:内部类可以直接访问外部类中的成员,外部类要访问内部类中的成员必须要创建对象。

 1 class Outer
 2 {
 3     int num = 4;
 4     //内部类。 
 5     class Inner
 6     {
 7         void method()
 8         {
 9             System.out.println("method run .."+Outer.this.num);
10         }
11     }
12     public void show()
13     {
14         Inner in = new Inner();
15         in.method();
16     }
17 }
18     
19 
20 class InnerClassDemo 
21 {
22     public static void main(String[] args) 
23     {
24         new Outer().show();
25     }
26 }

 

当内部类定义在外部类的成员位置上,可以使用一些成员修饰符修饰private,static。

1.默认修饰符。

  直接访问内部类的格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象;

Outer.Inner n in = = w new w Outer.new  Inner();// 这种形式很少用

  但是这种应用不多见,因为内部类之所以定义在内部就是为了封装,想要获取内部类的对象通常都通过外部类的方法获取,这样可以对内部类对象进行控制。

2.私有修饰符

  通常内部类被封装,都会被私有化,因为封装性不让其他程序直接访问,

3.静态修饰符

  如果内部类被静态修饰,相当于外部类,会出现访问局限性,只能访问外部类中的静态成员。

  注意:如果内部类中定义了内部成员,那么该内部类必须死静态的。

 

内部类编译后的文件名为:外部类名$内部类名.java

 

为什么内部类可以直接访问外部类中的成员呢?

  那是因为内部类都持有一个外部类的引用,这个引用是外部类名.this

  内部类可以定义在外部类中的成员位置上,也可以定义在外部类的局部位置上。

  当内部类被定义在局部位置上,只能访问局部中被final修饰的局部变量

匿名内部类

  凡是匿名的都是简写的形式,定义匿名内部类必须要有前提。

  前提:内部类需要继承或者实现一个外部的类或者接口,这时才能携程匿名内部类的形式。

  匿名内部类其实就是一个匿名子类对象,这个对象用{}结尾内部定义了成员,

匿名内部类的格式:new 父类名&接口名(){定义子类成员或者覆盖父类方法}.方法。

 

匿名内部类的使用场景:

  当函数的参数是接口类型的引用时,如果接口中的方法不超过3个。可以通过匿名内部类来完成参数的传递。

  其实就是在创建匿名内部类时,该类中的封装的方法不要过多,最好两个或者两个以内。

 

java之面向对象(二)

标签:

原文地址:http://www.cnblogs.com/yanghyun/p/4306174.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!