JavaSE复习:面向对象编程

         首先,面向对象(OOP:Object Oriented Programming)的相对词语是面向过程(POP:Procedure Oriented Programming)。

        面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做

        面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做

        面向对象更加强调运用人类 在日常的思维逻辑中 采用的思想方法与原则,如 抽象、分类、继承、聚合、多态等。

面向对象的三大特征(重中之重)

        封装 (Encapsulation)

        继承 (Inheritance)

        多态 (Polymorphism)

Java语言的基本元素:类和对象

 

 

常见的类的成员有:

        属 性:对应类中的成员变量

        行 为:对应类中的成员方法

Field = 属性 = 成员变量,Method = (成员)方法 = 函数

对象的创建和使用

        创建对象语法: 类名 对象名 = new 类名();

        使用“对象名.对象成员”的方式访问对象成员(包括属性和方法)

 

 

类的成员之一:属性(field)

 

 

 

类的成员之二:方法(method、函数)

        方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中 也称为函数或过程。

        将功能封装为方法的目的是,可以实现代码重用,简化代码

        Java里的方法不能独立存在,所有的方法必须定义在类里

        没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可 以不必使用return语句。如果使用,仅用来结束方法。

        方法中只能调用方法或属性,不可以在方法内部定义方法。

方法的重载(overload)

        在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。

        与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类 型)。调用时,根据方法参数列表的不同来区别。

重载示例:

//返回两个整数的和

int add(int x,int y){return x+y;}

//返回三个整数的和

int add(int x,int y,int z){return x+y+z;}

//返回两个小数的和

double add(double x,double y){return x+y;}

print(3); print(1.2f); print("hello!");

例如,System.out.println()方法就是典型的重载方法,其内部的声 明形式如下:

public void println(byte x)

public void println(short x)

public void println(int x)

public void println(long x)

public void println(float x)

public void println(double x)

public void println(char x)

public void println(double x)

public void println()

方法参数的值传递机制

 

面向对象特征之一:封装与隐藏

        我们程序设计追求“高内聚,低耦合”。

        高内聚 :类的内部数据操作细节自己完成,不允许外部干涉;

        低耦合 :仅对外暴露少量的方法用于使用。

        隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想

        使用者对类内部定义的属性(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题。

public class User {

    private Integer id;

    private String name;

    @JsonIgnore
    private String pwd;//保证用户信息的安全

    @JsonProperty("head_img")
    private String headImg;

    private String phone;
}

假如我把name属性修改为public,然后再创建另外的类里面写一个main方法,里面造一个User类

的对象,再对name属性直接赋值,就容易造成数据的混乱、不安全。

类的成员之三: 构造器(或构造方法)

        构造器的作用:创建对象;给对象进行初始化

        1.Java语言中,每个类都至少有一个构造器

        2.默认构造器的修饰符与所属类的修饰符一致

        3.一旦显式定义了构造器,则系统不再提供默认构造器

        4.一个类可以创建多个重载的构造器

        5.父类的构造器不可被子类继承

属性赋值过程

赋值的位置: ① 默认初始化 ② 显式初始化 ③ 构造器中初始化 ④ 通过“对象.属性“或“对象.方法”的方式赋值

赋值的先后顺序: ① - ② - ③ - ④

对JavaBean的理解:

        1.JavaBean是一种Java语言写成的可重用组件;

        2.所谓javaBean,是指符合如下标准的Java类:

                类是公共的

                有一个无参的公共的构造器

                有属性,且有对应的get、set方法

        3.用户可以使用 JavaBean 将 功能、处理、值、数据库访问 和其他任何可以用 Java代码创造的对象 进行打包,并且 其他的开发者可以通过 内部的JSP 页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用户可以认为 JavaBean提供了一种 随时随地的复制和粘贴的功能,而不用关心任何改变。

关键字—this

 

 

 

 

面向对象特征之二: 继承性(inheritance)

 

        缺点:继承让类与类之间产生了关系,类的耦合性增强,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性。

 

        Java只支持单继承和多层继承,不允许多重继承

                一个子类只能有一个父类

                一个父类可以派生出多个子类

 

方法的重写(override/overwrite)

        定义:在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法

        要求: 1. 子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表

                    2. 子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型

                    3. 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限

                        子类不能重写父类中声明为private权限的方法

                   4. 子类方法抛出的异常不能大于父类被重写方法的异常

        注意: 子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为 static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。

 

关键字:super

        在Java类中使用super来调用父类中的指定操作:

                super可用于访问父类中定义的属性

                super可用于调用父类中定义的成员方法

                super可用于在子类构造器中调用父类的构造器

        注意: 尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员

                   super的追溯不仅限于直接父类

                   super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识

 

 

 

 

面向对象特征之三: 多态性

        多态性,是面向对象中最重要的概念,在Java中的体现:

        对象的多态性:父类的引用指向子类的对象

                可以直接应用在抽象类和接口上

        Java引用变量有两个类型:编译时类型和运行时类型

        编译时类型由声明 该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简 称:编译时,看左边;运行时,看右边。

        若编译时类型和运行时类型不一致,就出现了对象的多态性(Polymorphism) 。

        多态情况下, “看左边” :看的是父类的引用(父类中不具备子类特有的方法)

                               “看右边” :看的是子类的对象(实际运行的是子类重写父类的方法)

 

 

 

方法的重载与重写

    所以这道面试题两个角度,定义的角度结合例子一定要说上,第二个编译和运行的角度根据实际情况大概讲一下,这道题就很完整了。 

 

 

 

 Object类的使用

补充:
clone():复制对象
finalize():垃圾回收器的方法,无引用指向该对象,把该对象进行回收(不要主动调用)

 

 

 

 

关键字:static

        如果想让一个类的所有实例共享数据,就用类变量!

开发中,如何确定一个属性是否要声明为static?
>属性可以被多个对象所共享的,不会随着对象的不同而不同的,例如账号。

如何确定一个方法是否要声明为static?
>操作静态属性的方法,通常设置为static的;
>工具类的方法,习惯上声明为static的,例如Math,Arrays,Collections

 

 

类方法(class method)

        1.没有对象的实例时,可以用类名.方法名()的形式访问由static修饰的类方法。

        2.在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。

        3.因为不需要实例就可以访问static方法,因此static方法内部不能有this。(也 不能有super ? YES!)

        4.static修饰的方法不能被重写

 

 

 饿汉式:

  1. 描述:这种方式比较常用,但容易产生垃圾对象。

  2. 优点:没有加锁,执行效率会提高。

  3. 缺点:类加载时就初始化,浪费内存。

懒汉式:(线程安全)

  1. 描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。

  2. 优点:第一次调用才初始化,避免内存浪费。

  3. 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。

 

 

类的成员之四: 代码块

         静态代码块:用static 修饰的代码块

                              1. 可以有输出语句。

                              2. 可以对类的属性、类的声明进行初始化操作。

                              3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。

                              4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。

                              5. 静态代码块的执行要先于非静态代码块。

                              6. 静态代码块随着类的加载而加载,且只执行一次

        非静态代码块:没有static修饰的代码块

                                1. 可以有输出语句。

                                2. 可以对类的属性、类的声明进行初始化操作。

                                3. 除了调用非静态的结构外,还可以调用静态的变量或方法。

                                4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。

                                5. 每次创建对象的时候,都会执行一次。且先于构造器执行。

 

关键字:final

         static final:全局常量

抽象类与抽象方法

        随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

 

 

 

接口(interface)

 

 

 jdk7前:可定义全局变量和抽象方法
jdk8:静态方法,默认方法

interface Network {
    public void browse();
}

// 被代理类
class RealServer implements Network {
    @Override
    public void browse() {
        System.out.println("真实服务器上网浏览信息");
    }
}

// 代理类
class ProxyServer implements Network {
    private Network network;

    public ProxyServer(Network network) {
        this.network = network;
    }

    public void check() {
        System.out.println("检查网络连接等操作");
    }

    public void browse() {
        check();
        network.browse();
    }
}

public class ProxyDemo {
    public static void main(String[] args) {
        Network net = new ProxyServer(newRealServer());
        net.browse();
    }
}

 

抽象和接口的区别:

分析:先从总体解释抽象和接口的基本概念,然后在比较两者之间的语法细节,最后再说一下两者的应用区别(或者两者分别举例子)

 抽象类的概念:

        含有abstract修饰符的class为抽象类。

        1.抽象类不能创建实例对象

        2.含有抽象方法的类必须定义为抽象类,而反过来抽象类中的方法不一定是抽象方法,也不必是抽象方法;

        3.抽象类中 定义抽象方法 必须在具体子类中实现,所以不能有抽象构造方法或抽象静态方法;

        4.如果其子类没有实现父类中的所有抽象方法,那么子类也必须定义为抽象类型。

接口的概念:

        可以说成是抽象类的一种特例,因为接口中的所有方法必须是抽象的。

        接口中的方法定义默认为public abstract类型,而接口中的成员变量类型默认为public static final。

两者的语法区别:

        1.构造方法:抽象类可以有构造方法,而接口中不能有构造方法;

        2.普通成员变量:抽象类可以有普通成员变量,而接口中没有普通成员变量;

        3.抽象方法:抽象类中可以包含非抽象的普通方法,而接口中的所有方法必须是抽象方法;

        4.访问类型:抽象类的抽象方法的访问类型可以是public、protected、default,而接口中的抽象方法只能是public类型的,默认为public abstract类型;

        5.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,而接口中定义的变量只能是public static final(全局变量);

        6.一个类可以实现多个接口,但只能继承一个抽象类。

两者在应用上的区别:

        接口更多的是在这个 系统架构设计方法 发挥作用,主要用于定义模块之间的通信协定。

        而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如模板方法设计模式是一个抽象类的典型应用:

public abstract class BaseServlet extends HttpServlet{

    public final void service(HttpServletRequest request,HttpServletResponse response)                                                      
        throw IOException,ServletException{
            //记录访问日志
            //进行权限判断
            /*if(具有权限){
                try{
                    deService(request,response);
                }catch(Exception e){
                    //记录异常信息
                }
            }
            */
    }
    
    protected abstract void doService(HttpServletRequest request,HttpServletResponse         
        response)throw IOException,ServletException{
        //访问权限定义为protected,因为是专门给子类用的
    }

}

public class MyServlet1 extends BaseServlet{
    protected void doService(HttpServletRequest request,HttpServletResponse         
        response)throw IOException,ServletException{
        //本Servlet只处理具体的业务逻辑代码
    }

}

         假如某个项目的所有Servlet类都要用到相同的方式进行 记录访问日志、权限判断和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成 记录访问日志、权限判断和处理异常 的代码,在各个子类中只是完成各自的业务逻辑代码。

        所以,父类方法中间的某段代码不确定,留给子类来干,就用模板方法设计模式。

 

 

类的内部成员之五: 内部类

        当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。

        在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。

        Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。                 Inner class的名字不能与包含它的外部类类名相同

分类: 成员内部类(static成员内部类和非static成员内部类)

            局部内部类(不谈修饰符)、匿名内部类

 

局部内部类

 匿名内部类

        匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类

匿名内部类的特点:

1.匿名内部类必须继承父类或实现接口

2.匿名内部类只能有一个对象

3.匿名内部类对象只能使用多态形式引用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值