面向对象
一、java面向对象基础
1、面向对象和面向过程
二者相辅相成。宏观上使用面向对象把握,微观处理上仍然是面向过程。
面向过程:一步一步的做;适合简单、不需要协作的任务,比如“如何造车”列出1234这样的步骤是不可能的,需要协作才能完成。
面向对象:考虑的是“车怎么设计”而不是“怎么按步骤造车”。
2、对象的理解—本质上是一种数据组织方式
比如,我们的一个学生对象:
有属性(静态特征):年龄:18,姓名:高淇,学号:1234
也可以有方法(动态行为):学习,吃饭,考试
3、类和对象
对象是具体的事物;类是对对象的抽象;
类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。
4、关于类
(1)每一个源文件必须有且只有一个public class,并且类名和文件名保持一致。
一个java文件可以同时定义多个class。
(2)内存分析
栈:栈描述的是方法执行的内存模型,每个方法被调用都会创建一个栈帧。
堆:堆用于存储创建好的对象和数组(数组也是对象),JVM只有一个堆,被所有线程共享。
方法区(又叫静态区):用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)。
(3)构造方法
构造方法名和类名保持一致;通过new关键字调用;不能在构造器使用return返回某个值;如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义则编译器不会自动添加!
构造方法的第一句总是super()
5、垃圾回收机制
发现无用对象(没有任何变量引用该对象),回收无用对象的空间。
引用可达法(了解概念即可)
分代垃圾回收机制:年轻代、年老代、持久代
Minor GC、Major GC、Full GC
6、this
对象创建过程:
this代表当前对象,创建好的对象的地址。
this调用构造器:使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
static类不能使用this。
7、static
在static方法中不可直接访问非static的成员。
static修饰的成员变量和方法,从属于类。
普通变量和方法从属于对象.
8、静态初始化块
用于类的初始化操作。上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到我们的类的静态初始化块为止。构造方法执行顺序和上面顺序一样。
9、参数传值机制
“值传递”,传递的是值的副本。
1、基本数据类型参数传值:传递的是值的副本。 副本改变不会影响原件。
2、引用类型参数的传值:引用类型是指“对象的地址”,副本和原参数都指向了同一个地址,改变副本指向地址对象的值,也意味着原参数指向对象的值也发生了改变。
10、包
包类似文件夹,管理类。
jdk中主要的包
java.lang:不用导入可直接使用,包含一些java语言的核心类
还有:java.awt; java.net; java.io; java.util
导入:import
静态导入:import static java.lang.Math.*;
二、面向对象进阶
三大特性:继承、封装、多态
1、继承–instance of
class Student extend Person
选中类,ctrl+T,查看类的继承树结构。
instanceof判断是否是继承关系。
继承使用要点:
(1)父类也称作超类、基类、派生类等。
(2)Java中只有单继承,没有像C++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。
(3)Java中类没有多继承,接口有多继承。
(4)子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)。
(5)如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
2、方法重写override
三个条件:
(1)“==”: 方法名、形参列表相同。
(2)“≤”:返回值类型和声明异常类型,子类小于等于父类。
(3)“≥”: 访问权限,子类大于等于父类。
3、Object类
是所有java类的根基类,默认继承
(1)Object类中定义有public String **toString()**方法,在打印输出或者用字符串连接对象时,会自动调用该对象的toString()方法。
(2)“==”代表比较双方是否相同。如果是基本类型则表示值相等,如果是引用类型则表示地址相等即是同一个对象。 Object类中定义有:public boolean equals(Object obj)方法,提供定义“对象内容相等”的逻辑。
经常重写equals方法,右键source-generate hascode() and equals()
4、super关键字
若是构造方法的第一行代码没有显式的调用super(…)或者this(…);那么Java默认都会调用super(),含义是调用父类的无参数构造方法。
通过super来访问父类中被子类覆盖的方法或属性。
构造方法第一句总是:super(…)来调用父类对应的构造方法。
5、封装
“高内聚”:封装细节;“低耦合”:简化外部调用。
规则:属性私有,提供相应的set、get方法;方法public
自动生成:eclipse–source–generate setters and getters
6、多态
多态指的是同一个方法的调用,是方法的多态。
多态存在要有3个必要条件:继承、方法重写、父类引用指向子类对象。
父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。
7、对象的转型casting
向上转型:父类引用指向子类对象,我们称这个过程为向上转型,属于自动类型转换。
向下转型:Dog dog=(Dog)animal
8、final
final修饰变量则变量不可改变;修饰方法,此方法不可被子类重写,但可以被重载;修饰类,修饰的类不能被继承。
9、抽象方法和抽象类–abstract
(1)有抽象方法的类只能定义成抽象类
(2)抽象类不能实例化,即不能用new来实例化抽象类。
(3)抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。
(4)抽象类只能用来被继承。
(5)抽象方法必须被子类实现
10、接口interface
接口是一种契约。
定义接口:
public interface MyInterface extends FatherInterface{
//常量定义;接口中的属性只能是常量
//方法定义;接口中方法只能是public abstract
}
class c implements MyInterface{
//实现接口
}
一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。
接口可以多继承。但类只能单继承。
多继承:
interface A {
void testa();
}
interface B {
void testb();
}
/**接口可以多继承:接口C继承接口A和B*/
interface C extends A, B {
void testc();
}
public class Test implements C {
public void testc() {
}
public void testa() {
}
public void testb() {
}
}
11、内部类
把一个类放在另一个类的内部定义,称为内部类(innerclasses)。
为什么要用内部类:提供了更好的封装性;内部类可以直接访问外部类的私有属性。但外部类不能访问内部类的内部属性。
分类:成员内部类(非静态内部类、静态内部类);匿名内部类;局部内部类
非静态内部类:不能有静态方法、静态属性和静态初始化块; 外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例。
class Outer{
private int age=10;
class Inner{
int age=20;
public void show() {
int age=30;
System.out.println(age);# 内部类里方法的局部变量:变量名
System.out.println(this.age);#内部类属性:this.变量名
System.out.println(Outer.this.age);#外部类属性:外部类名.this.变量名。
}
}
}
Outer.Inner inner = new Outer().new Inner();#访问内部类
静态内部类:静态内部类看做外部类的一个静态成员。当一个静态内部类对象存在,并不一定存在对应的外部类对象。 因此,静态内部类的实例方法不能直接访问外部类的实例方法。
外部类的方法中可以通过:“静态内部类.名字”的方式访问静态内部类的静态成员。
class Outer{
static class Inner{
}
}
Outer.Inner inner=new Outer.Inner();
匿名内部类:作用域只限于本方法。
this.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
12、String类
String str1="abc";
String str2=new String("abc");
str1==str2;//false
str1.equals(str2)//true
常用方法:
s.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
12、String类
```java
String str1="abc";
String str2=new String("abc");
str1==str2;//false
str1.equals(str2)//true
常用方法:
参考:https://www.sxt.cn/Java_jQuery_in_action/Object_evolutionary_history.html