- 面向对象就是一种常见的思想,符合人们的思考习惯
- 面向对象的出现将复杂的事情简单化
- 面向对象的出现将我们的身份由执行者转变成为了指挥者
- 面向对象的重点只需要关注两个:
- 有没有这个对象
- 对象里面具不具备这样的功能
就是不断的创建对象,使用对象,指挥对象做事情,有对象就找这个对象做事情,没有对象自己创建 一个对象,使其拥有这样的功能,其他人也可以使用这个对象
其实就是在管理和维护对象之间的关系
封装、继承、多态、抽象
用Java语言描述现实中的事物,通过类的形式来体现,对于事物的描述通常只关注两个方面: 一个是属性、一个是行为(功能、方法),只要明确该事物的属性和行为并定义在类中即可
- 类:对某一类事物的描述(属性、行为)
- 对象:该类事物的实例,在java中通过new的方式创建
- 作用域
- 成员变量定义在类中,整个类都可以访问
- 局部变量定义在方法中,语句(for循环)中,局部代码块中,只在所属的区域有效
- 变量的存在那块内存
- 成员变量存在于堆内存的对象中
- 局部变量存在于栈内存的方法中
- 生命周期
- 成员变量随着对象的创建而存在,随着对象的消失而消失
- 局部变量随着所属区域的执行而存在,随着所属的结束而释放
- 是否有默认值
- 成员变量有默认的初始化值
- 局部变量没有默认的初始化值
是指将属性私有化,对外提供公共的访问形式(getter,setter) 注意:私有仅仅是封装的一种体现
- 特点:
- 构造器的名称与类名相同
- 构造器不用定义返回值类型
- 构造器没有具体的返回值
- 作用:
- 给对象进行初始化
- 注意:
- 默认构造器的特点
- 一个类中多个构造器是以"重载"的形式体现的
- 重载:
- 方法名相同,参数列表不同
-
用法1: 当成员变量和局部变量重名时,可以使用this来区分 this:代表对象,代表当前对象,this就是所在方法所属对象的引用。简单说:就是哪个对象调用this所在的方法 this就代表哪一个对象
-
用法2: this还可以在构造器中调用构造器
抽象:笼统、模糊、看不懂、不具体
-
抽象类的特点:
- 方法只有声明没有实现时(没有方法体),该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中,该类也必须使用abstract修饰
- 抽象类不可以被实例化(不可以被new)因为调用抽象方法没有意义
- 抽象类必须由其子类覆盖了所有的抽象方法后,该子类才可以实例化,否则,这个子类还是一个抽象类
- 抽象类和抽象方法非常适合做"系统的分析和设计的工具"
-
问题:
-
抽象类中有构造器吗? 有,可以给子类对象进行初始化
-
抽象类中可以不定义抽象方法吗? 可以,但是很少见 适配器类
abstract class A{ void show1(){} void show2(){}
}
-
抽象(abstract)关键字不可以和下列哪些关键字共存? private不行,抽象方法需要被覆盖 static不行 final不行
-
抽象类一定是父类吗? 一定是
-
抽象类和一般了类的异同 相同点: 抽象类和一般类都是用来描述事物, 都在内部定义了成员 不同点: 1)一般类有足够的信息描述事物 抽象类描述事物的信息可能不足 2)一般类中不能定义抽象方法,只能定义非抽象方法 抽象类中可以定义抽象方法,也可以定义非抽象方法 3)一般类可以被实例化 抽象类不能被实例化
-
-
class 类名{} interface 接口名{} 接口中的成员修饰符都是固定的: 成员常量:
public static final成员方法:public abstract -
类和类之间是继承(extends)关系, 类和接口之间是实现(implements)关系, 接口不可以被实例化,只能有实现了接口的子类并覆盖接口中所有的抽象方法后,该子类才可以实例化,否则这个子类 依旧是一个抽象类。
接口的出现将"多继承"通过另外一种形式表现出来,即"多实现",一个类还可以在继承一个类的同时实现多个接口,避免单继承的局限性
-
接口是一个特殊的抽象类(纯抽象类)
-
接口是程序的功能扩展
-
接口的出现降低耦合性 耦合性: 也称为块间联系。指软件系统结构中各模块 间相互联系紧密程度的一种度量 内聚性: 也称为块内联系。指的是一个模块内部各个 元素彼此结合紧密程度的一种度量
interface T{} class T1 implements T{} class T2 implements T{} say(T t){}
-
接口可以用来多实现
-
类与接口之间是实现关系,而且类可以在继承,一个类的同时实现多个接口
-
接口的属性默认是常量,而且是public static final修饰的
-
接口中的方法一定是public abstract修饰的(public abstract可以省略不写)
-
接口和接口之间可以有多继承关系
-
接口中没有构造器
- 相同点: 都是不断向上抽取而来的
- 不同点:
- 抽象类需要被继承,而且只能被单继承,接口需要被实现,而且可以多实现
- 抽象类中可以定义抽象方法和非抽象方法,子类继承后可以直接使用抽象类中非抽象方法,接口中只能定义抽象方法,必须由子类去实现
- 抽象类的继承,是is a关系,在定义该体系的基本共性内容接口的实现,是like a关系,在定义该体系的额外功能
修饰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 一起修饰
方法的多态:方法的重载 对象的多态:父类型(父接口)的引用指向子类的对象
class Animal{}
class Cat extends Animal{}
Cat c = new Cat();
Animal a = new Cat();向上转型的目的就是限制功能的使用,为了提高代码的扩展性(统一操作动物)。 向下转型的目的就是为了使用子类的特有功能
java中的instanceof是一个二元运算符,它的作用是用来判断instanceof左边的对象是否属于右边类的实例,返回一个boolean类型的结果
-
成员变量
- 编译时:参考引用类型变量所属的类中是否有调用的成员变量,有,编译通过,没有,编译失败
- 运行时:参考引用类型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量
- 简单说:编译和运行都参考赋值符号的左边
-
成员方法(非静态的)
- 编译时:参考引用类型变量所属的类中是否有调用的成员方法,有,编译通过,没有,编译失败
- 运行时:参考对象所属的类中是否有调用的成员方法
- 简单说:编译看左边,运行看右边
JavaBean指的是符合某种特定规范的Java类
- 所有的属性均为private
- 提供默认的构造器
- 提供getter和setter方法
- 实现serializable接口(序列化接口)
特点:
- static是一个修饰符,用于修饰成员
- static修饰的成员被该类的所有对象所共享
- static优先于对象而存在,因为static修饰的 成员随着类的加载就已经存在了
- static修饰的成员多了一种调用方式,可以直接 被类名调用,类名.静态成员
- static修饰的数据是共享数据,对象中存储的数据 是特有数据
-
两个变量的生命周期不同 成员变量随着对象的创建而存在,随着对象被回收而释放,
静态变量随着类的加载而存在,随着类的消失而消失
-
调用方式不同 成员变量只能被对象调用 静态变量可以被对象调用,还可以被类名调用
-
别名不同 成员变量也叫作实例变量 静态变量也叫作类变量
-
数据的存储位置不同 成员变量数据存储在堆内存的对象中,所以也叫作对象的特有数据 静态变量数据存储在方法区的静态方法区中(数据共享区),所以也叫作对象的共享数据
-
静态变量 当分析对象中所具备的成员变量的值都是相同的,这时这个成员变量就可以被静态修饰,只要数据在对象中是不同的,那就是对象的特有数据,必须 存储在对象中,就不能定义成静态的
-
静态方法 方法是否用静态修饰,就参考一点,该方法的功能是否有访问到对象中的特有数据,如果有,就不能定义成静态的,如果没有,就可以定义成静态的
-
静态代码块
定义在类中 static{
}
-
构造代码块:定义在类中 {}
-
一个类中有静态代码块、构造代码块、构造器,它们的执行顺序是什么?
-
继承(extends) 好处:
- 提高代码的复用性
- 让类与类之间产生了关系,为多态这个特征提供了前提
-
Java中的单继承和多继承 Java中支持单继承,不直接支持多继承,但是对C++中的多继承机制进行了改良
-
单继承:一个子类只能有一个直接父类
-
多继承:一个子类可以有多个直接父类(java中不允许) 示例:
class A{} class B{} class C extends B{} class C extends B,A{}-->错误语法
-
-
Java支持多层(重)继承
// 举例: class Demo{ void show1(){} } class DemoA extends Demo{ void show2(){} } class DemoB extends Demo{ void show3(){} }
-
什么时候定义继承 当类与类之间存在着所属关系时,就定义继承,X是Y的一种,X extends Y
-
在子父类中,成员的特点体现
-
成员变量。当本类的成员变量和局部变量重名时用this区分。当子父类中的成员变量重名时,用super区分父类 this和super的用法很相似 this:代表的是一个本类对象的引用 super:代表的是父类的空间
-
成员方法 当子父类中出现成员方法一模一样的情况,会运行子类中的方法,这种现象,称为覆盖操作,也叫作方法的重写。这是方法在子父类中的特性。
-
-
方法的两个特性:
-
重载,发生在同一个类中。overload
-
覆盖(重写),在子类中重写父类的方法。
override重写的注意事项:
- 子类重写父类的方法时,子类的权限必须要大于或者等于父类的权限
- 静态只能覆盖静态或者被静态覆盖
-
-
构造方法 子类继承了父类,获取到父类中的内容(属性),所以在使用父类的内容之前,要先看父类是如何对自己的内容进行初始化的,所以子类在构造对象时,必须访问父类中的构造器,为了完成这个必须的动作,就在子类构造器中加入super()语句,如果父类中没有无参构造器,那么子类的构造器中必须使用super明确的调用父类的有参构造器,同时子类构造器中如果使用了this调用了本类的其他构造器,那么super就没用了,因为super和this都必须定义在第一行,所以只能有一个,但是可以保证的是,子类中肯定会有其他的构造器,能够访问父类的构造器
-
对象在内存中实例化过程:
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); } }
-