java之面向对象(二)

主要知识点:

  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 吼叫();
}

class 狗 extends 犬科
{
    void 吼叫()
    {
        System.out.println("汪汪");
    }
}
class 狼 extends 犬科
{
    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个。可以通过匿名内部类来完成参数的传递。

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

时间: 2024-10-09 23:24:36

java之面向对象(二)的相关文章

Java实验报告二:Java面向对象程序设计

Java实验报告二:Java面向对象程序设计                                                                                                      实验要求: 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计模式 实验内容 (一)单元测试 (二)面向对象三要素 (三)设计模式初步 (四)练习

java 基础(二)

java 基础(二)java 基础(二) 2016-2-1 by Damon 61. 编写多线程程序有几种实现方式 Java 5以前实现多线程有两种实现方法:一种是继承Thread类:另一种是实现Runnable接口.两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活. 补充:Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的

java基础面向对象之this关键字

java基础面向对象之this关键字 2017-02-14 this的核心概念: this关键字在java中表示当前对象. this关键字的主要用法: 在java中利用this关键字可以实现类属性的调用,类方法的调用,当前对象. 一.调用属性 1 class Book{ //Book类 2 private String title ; //title属性 3 private int price ; //price属性 4 5 public Book(String t , int p){ 6 ti

Java之面向对象相关问题集

面向对象的特征有哪些方面  1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一是过程抽象,二是数据抽象. 2.封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面.面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治.封装的对象,这些对象通过一个受保护的接口访问其他对象. 3.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重

Java与面向对象

一.面向过程的思想和面向对象的思想 面向对象和面向过程的思想有着本质上的区别, 作为面向对象的思维来说,当你拿到一个问题时,你分析这个问题不再是第一步先做什么,第二步再做什么,这是面向过程的思维,你应该分析这个问题里面有哪些类和对象,这是第一点,然后再分析这些类和对象应该具有哪些属性和方法.这是第二点.最后分析类和类之间具体有什么关系,这是第三点. 面向对象有一个非常重要的设计思维:合适的方法应该出现在合适的类里面 二.简单理解面向对象 就是在程序里面首先分解出来的应该是注意不再是一步一步的过程

Java面试题(二)

系统整理了一下有关Java的面试题,包括基础篇,javaweb篇,框架篇,数据库篇,多线程篇,并发篇,算法篇等等,陆续更新中.其他方面如前端后端等等的面试题也在整理中,都会有的. 注:文末有福利! 1.String s = new String("xyz");创建了几个StringObject?是否可以继承String类? 两个或一个都有可能,"xyz"对应一个对象,这个对象放在字符串常量缓冲区,常量"xyz"不管出现多少遍,都是缓冲区中的那一个

Java设计模式(二)-单例模式

单例模式建议保证某个对象仅仅只有一个实例,当只有一个对象来协调整个系统的操作时,在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例,总之,选择单例模式就是为了避免不一致状态,避免政出多头. 下面是单例模式的类图:包括的private和static修饰的实例instance.一个private的构造函数.一个static的getInstance函数 单例模式主要有三种:懒汉式单例.饿汉式单例.登记式单例三种 1.饿汉式单例:在类的初始化时候,自行创建了实例 c

【转】java提高篇(二)-----理解java的三大特性之继承

[转]java提高篇(二)-----理解java的三大特性之继承 原文地址:http://www.cnblogs.com/chenssy/p/3354884.html 在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句话中最引人注目的是"复用代码",尽可能的复用代码使我们程序员一直在追求的,现在我来介绍一种复用代码的方式,也是java三大

Java数据结构之二叉搜索树

Java数据结构之二叉搜索树 1.二叉搜索树组成 二叉搜索树又称为二叉排序树,它或者是一颗空树,或者是一颗具有如下特性的非空二叉树,需要满足一下三个条件: (1)若它的左子树非空,则左子树上所有结点的关键字均小于根结点的关键字: (2)若它的右子树非空,则右子树上所有结点的关键字均大于(可以等于)根结点的关键字. (3)左子树右子树本身又各是一颗二叉搜索树 在算法描述中,均以结点值的比较来代表其关键字的比较,因为若结点的值为类类型时,该类必须实现系统提供的java.lang.comparable