Skip to content

Latest commit

 

History

History
executable file
·
389 lines (295 loc) · 14.2 KB

File metadata and controls

executable file
·
389 lines (295 loc) · 14.2 KB

面向对象

1. 面向对象思想

  1. 面向对象就是一种常见的思想,符合人们的思考习惯
  2. 面向对象的出现将复杂的事情简单化
  3. 面向对象的出现将我们的身份由执行者转变成为了指挥者
  4. 面向对象的重点只需要关注两个:
    • 有没有这个对象
    • 对象里面具不具备这样的功能

2. 面向对象开发

就是不断的创建对象,使用对象,指挥对象做事情,有对象就找这个对象做事情,没有对象自己创建 一个对象,使其拥有这样的功能,其他人也可以使用这个对象

3. 面向对象设计

其实就是在管理和维护对象之间的关系

4. 面向对象特征

封装、继承、多态、抽象

5. 类和对象之间的关系

用Java语言描述现实中的事物,通过类的形式来体现,对于事物的描述通常只关注两个方面: 一个是属性、一个是行为(功能、方法),只要明确该事物的属性和行为并定义在类中即可

  1. 类:对某一类事物的描述(属性、行为)
  2. 对象:该类事物的实例,在java中通过new的方式创建

6. 成员变量和局部变量的区别

  1. 作用域
    • 成员变量定义在类中,整个类都可以访问
    • 局部变量定义在方法中,语句(for循环)中,局部代码块中,只在所属的区域有效
  2. 变量的存在那块内存
    • 成员变量存在于堆内存的对象中
    • 局部变量存在于栈内存的方法中
  3. 生命周期
    • 成员变量随着对象的创建而存在,随着对象的消失而消失
    • 局部变量随着所属区域的执行而存在,随着所属的结束而释放
  4. 是否有默认值
    • 成员变量有默认的初始化值
    • 局部变量没有默认的初始化值

7. 封装思想

是指将属性私有化,对外提供公共的访问形式(getter,setter) 注意:私有仅仅是封装的一种体现

8. 构造方法(Constructor)

  1. 特点:
    • 构造器的名称与类名相同
    • 构造器不用定义返回值类型
    • 构造器没有具体的返回值
  2. 作用:
    • 给对象进行初始化
  3. 注意:
    • 默认构造器的特点
    • 一个类中多个构造器是以"重载"的形式体现的
  4. 重载:
    • 方法名相同,参数列表不同

9. this关键字

  • 用法1: 当成员变量和局部变量重名时,可以使用this来区分 this:代表对象,代表当前对象,this就是所在方法所属对象的引用。简单说:就是哪个对象调用this所在的方法 this就代表哪一个对象

  • 用法2: this还可以在构造器中调用构造器

10. 抽 象类(abstract)

抽象:笼统、模糊、看不懂、不具体

  1. 抽象类的特点:

    • 方法只有声明没有实现时(没有方法体),该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中,该类也必须使用abstract修饰
    • 抽象类不可以被实例化(不可以被new)因为调用抽象方法没有意义
    • 抽象类必须由其子类覆盖了所有的抽象方法后,该子类才可以实例化,否则,这个子类还是一个抽象类
    • 抽象类和抽象方法非常适合做"系统的分析和设计的工具"
  2. 问题:

    • 抽象类中有构造器吗? 有,可以给子类对象进行初始化

    • 抽象类中可以不定义抽象方法吗? 可以,但是很少见 适配器类

       abstract class A{
       void show1(){}
        void show2(){}

    }

    • 抽象(abstract)关键字不可以和下列哪些关键字共存? private不行,抽象方法需要被覆盖 static不行 final不行

    • 抽象类一定是父类吗? 一定是

    • 抽象类和一般了类的异同 相同点: 抽象类和一般类都是用来描述事物, 都在内部定义了成员 不同点: 1)一般类有足够的信息描述事物 抽象类描述事物的信息可能不足 2)一般类中不能定义抽象方法,只能定义非抽象方法 抽象类中可以定义抽象方法,也可以定义非抽象方法 3)一般类可以被实例化 抽象类不能被实例化

    
    

11. 接口(interface)

  • class 类名{} interface 接口名{} 接口中的成员修饰符都是固定的: 成员常量:public static final 成员方法:public abstract

  • 类和类之间是继承(extends)关系, 类和接口之间是实现(implements)关系, 接口不可以被实例化,只能有实现了接口的子类并覆盖接口中所有的抽象方法后,该子类才可以实例化,否则这个子类 依旧是一个抽象类。

    接口的出现将"多继承"通过另外一种形式表现出来,即"多实现",一个类还可以在继承一个类的同时实现多个接口,避免单继承的局限性

11.1 接口的特点

  • 接口是一个特殊的抽象类(纯抽象类)

  • 接口是程序的功能扩展

  • 接口的出现降低耦合性 耦合性: 也称为块间联系。指软件系统结构中各模块 间相互联系紧密程度的一种度量 内聚性: 也称为块内联系。指的是一个模块内部各个 元素彼此结合紧密程度的一种度量

    interface T{}
    class T1 implements T{}
    class T2 implements T{}
    say(T t){}
  • 接口可以用来多实现

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

  • 接口的属性默认是常量,而且是public static final修饰的

  • 接口中的方法一定是public abstract修饰的(public abstract可以省略不写)

  • 接口和接口之间可以有多继承关系

  • 接口中没有构造器

11.2 接口和抽象类的异同

  • 相同点: 都是不断向上抽取而来的
  • 不同点:
    1. 抽象类需要被继承,而且只能被单继承,接口需要被实现,而且可以多实现
    2. 抽象类中可以定义抽象方法和非抽象方法,子类继承后可以直接使用抽象类中非抽象方法,接口中只能定义抽象方法,必须由子类去实现
    3. 抽象类的继承,是is a关系,在定义该体系的基本共性内容接口的实现,是like a关系,在定义该体系的额外功能

11.3 访问控制修饰符

修饰java类、属性、方法的访问可见范围)

修饰符(1表示可访问) 类内 包内 子类 任意位置
public 1 1 1 1
protected 1 1 1
default 1 1
private 1

private:私有的,仅仅在类的内部可见 public:公有的,任意位置可见(类内部、 同一个包下、子类和其他地方) protected:受保护的,在同一个包中和子类中可见 default:默认的,什么都不写,在同一个包中可见

final关键字(最终的) final是一个修饰符,可以修饰类、方法、变量 final修饰的类不可以被继承(例如:String/Math/Integer...) final修饰的方法不可以被覆盖(重写) final修饰的变量是一个常量,只能赋值一次,如果尝试第二次修改值,那么会编译错误 成员变量一旦被final修饰之后就是固定不变, 是所有对象能共享的资源,所以一般都会加static 一起修饰

11.4 多态

方法的多态:方法的重载 对象的多态:父类型(父接口)的引用指向子类的对象

class Animal{}
class Cat extends Animal{}
Cat c = new Cat();
Animal a = new Cat();
11.4.1 转型的目的

向上转型的目的就是限制功能的使用,为了提高代码的扩展性(统一操作动物)。 向下转型的目的就是为了使用子类的特有功能

11.4.2 instanceof运算符

java中的instanceof是一个二元运算符,它的作用是用来判断instanceof左边的对象是否属于右边类的实例,返回一个boolean类型的结果

11.4.3 多态的特点
  1. 成员变量

    • 编译时:参考引用类型变量所属的类中是否有调用的成员变量,有,编译通过,没有,编译失败
    • 运行时:参考引用类型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量
    • 简单说:编译和运行都参考赋值符号的左边
  2. 成员方法(非静态的)

    • 编译时:参考引用类型变量所属的类中是否有调用的成员方法,有,编译通过,没有,编译失败
    • 运行时:参考对象所属的类中是否有调用的成员方法
    • 简单说:编译看左边,运行看右边

11.5 JavaBean

JavaBean指的是符合某种特定规范的Java类

11.5.1 JavaBean规范
  1. 所有的属性均为private
  2. 提供默认的构造器
  3. 提供getter和setter方法
  4. 实现serializable接口(序列化接口)

11.6 static关键字(静态的)

特点:

  1. static是一个修饰符,用于修饰成员
  2. static修饰的成员被该类的所有对象所共享
  3. static优先于对象而存在,因为static修饰的 成员随着类的加载就已经存在了
  4. static修饰的成员多了一种调用方式,可以直接 被类名调用,类名.静态成员
  5. static修饰的数据是共享数据,对象中存储的数据 是特有数据

11.7 成员变量和静态变量的区别

  1. 两个变量的生命周期不同 成员变量随着对象的创建而存在,随着对象被回收而释放,

    静态变量随着类的加载而存在,随着类的消失而消失

  2. 调用方式不同 成员变量只能被对象调用 静态变量可以被对象调用,还可以被类名调用

  3. 别名不同 成员变量也叫作实例变量 静态变量也叫作类变量

  4. 数据的存储位置不同 成员变量数据存储在堆内存的对象中,所以也叫作对象的特有数据 静态变量数据存储在方法区的静态方法区中(数据共享区),所以也叫作对象的共享数据

11.7.1 静态什么时候用
  1. 静态变量 当分析对象中所具备的成员变量的值都是相同的,这时这个成员变量就可以被静态修饰,只要数据在对象中是不同的,那就是对象的特有数据,必须 存储在对象中,就不能定义成静态的

  2. 静态方法 方法是否用静态修饰,就参考一点,该方法的功能是否有访问到对象中的特有数据,如果有,就不能定义成静态的,如果没有,就可以定义成静态的

  3. 静态代码块

    定义在类中 static{

    }

  4. 构造代码块:定义在类中 {}

11.8 面试题

  1. 一个类中有静态代码块、构造代码块、构造器,它们的执行顺序是什么?

  2. 继承(extends) 好处:

    • 提高代码的复用性
    • 让类与类之间产生了关系,为多态这个特征提供了前提
  3. Java中的单继承和多继承 Java中支持单继承,不直接支持多继承,但是对C++中的多继承机制进行了改良

    • 单继承:一个子类只能有一个直接父类

    • 多继承:一个子类可以有多个直接父类(java中不允许) 示例:

      class A{}
      class B{}
      class C extends B{}
      class C extends B,A{}-->错误语法
  4. Java支持多层(重)继承

    // 举例:
    class Demo{
    	void show1(){}
    }
    class DemoA extends Demo{
    	void show2(){}
    }
    class DemoB extends Demo{
    	void show3(){}
    }
  5. 什么时候定义继承 当类与类之间存在着所属关系时,就定义继承,X是Y的一种,X extends Y

  6. 在子父类中,成员的特点体现

    • 成员变量。当本类的成员变量和局部变量重名时用this区分。当子父类中的成员变量重名时,用super区分父类 this和super的用法很相似 this:代表的是一个本类对象的引用 super:代表的是父类的空间

    • 成员方法 当子父类中出现成员方法一模一样的情况,会运行子类中的方法,这种现象,称为覆盖操作,也叫作方法的重写。这是方法在子父类中的特性。

  7. 方法的两个特性:

    1. 重载,发生在同一个类中。overload

    2. 覆盖(重写),在子类中重写父类的方法。

      override重写的注意事项:

      • 子类重写父类的方法时,子类的权限必须要大于或者等于父类的权限
      • 静态只能覆盖静态或者被静态覆盖
  8. 构造方法 子类继承了父类,获取到父类中的内容(属性),所以在使用父类的内容之前,要先看父类是如何对自己的内容进行初始化的,所以子类在构造对象时,必须访问父类中的构造器,为了完成这个必须的动作,就在子类构造器中加入super()语句,如果父类中没有无参构造器,那么子类的构造器中必须使用super明确的调用父类的有参构造器,同时子类构造器中如果使用了this调用了本类的其他构造器,那么super就没用了,因为super和this都必须定义在第一行,所以只能有一个,但是可以保证的是,子类中肯定会有其他的构造器,能够访问父类的构造器

  9. 对象在内存中实例化过程: Person p = new Person();

    • JVM会读取指定路径下的Person.class文件,并加载进内存,并会先加载Person的父类(如果有直接父类的情况下)

    • 在堆内存中开辟空间,分配地址

    • 并在对象的空间中,对对象的属性进行默认初始化

    • 调用对应的构造器进行初始化

    • 在构造器中,第一行会先调用父类的构造器进行初始化

    • 父类初始化完毕之后,再对子类的属性进行显示初始化

    • 再进行子类构造器的特定初始化

    • 初始化完毕之后,将地址赋值给引用变量

      class A{
      	public A(){}
      }  
      class B extends A(){
      	int x = 10;
      	int y = 90;
      	public B(int x,int y){
      		super();
      		//显示初始化
      		this.x = x;
      		this.y = y;
      	}
      }
       class Demo{
       	main(){
       		B b = new B(3,4);
       	}
       }