1.面向对象思想编程内容的三条主线分别是什么?
(1)类即类的成员:属性、方法、构造器;代码块、内部类;
(2)面向对象的三大特征:封装、继承、多态;
(3)其他关键字:this,super,abstract,interface,final,package,import
2.面向对象与面向过程
面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做
面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做
3.面向对象中两个重要的概念
类:对一个类事物的的描述,是抽象的、概念上的定义
对象:是实际存在的该类事物的每个个体,因而也称为实例(instance)
对象,是由类new出来,派生出来的。
4.面向对象思想落地实现的规则
(1)创建类
(2)类的实例化
(3)调用对象的结构:对象.属相、对象.方法
Tip:
属性 = 成员变量 = field = 域、字段
方法 = 成员方法 = 函数 = method
创建类的对象 = 类的实例化 = 实例化类
5.属性与局部变量的区别
相同点:
(1)定义变量的个格式:数据类型 变量名 = 变量值 ;
(2)先声明,后使用
(3)变量都其对应的作用域
不同点:
(1)在类中声明的位置不同
属性:直接定义在类的一对{}内
局部变量:声明在方法内部、方法形参、代码块内、构造器形参、构造器内部变量
(2)关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符。
常用的权限修饰符:private, public, 缺省, protected -->封装性
局部变量:不可以使权限修饰符
(3)默认初始化值的情况
属性:类的属性,根据其类型,都有默认初始化值
整型(byte, short, int, long):0
浮点型(float, double):0.0
字符型(char):0或'\u0000'
布尔型(boolean):false
引用类型(类, 数组, 接口):null
局部变量:没有默认初始化值
意味着,我们调用局部变量之前,一定显式赋值。
特别地,形参在调用时,我们赋值即可
(4)在内存中加载的位置
属性:加载在堆空间中(非static)
局部变量:加载到栈内存
6.变量的分类
(1)按类型分类
(2)按在类中声明的位置
7.return关键字
(1)使用范围:使用在方法体中
(2)作用:①结束方法
②针对于返回值类型的方法,使用"return 数据"方法返回所要的数据
(3)注意点:return关键字后面不可以声明执行语句
8.方法的重载的概念
(1)定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
"两同一不同":同一个类、方法名相同
参数列表不同:参数个数不同,参数类型不同
(2)例子:Arrays类中重的sort() / binarySeearch();PrintStream类中的println()
(3)如何判断是否构成方法的重载?
按照两同一不同,跟方法的全权限修饰符、返回值、形参变量名、方法体都没关系
9.可变特性形参
(1)可变个数形参的格式:数据类型 ... 变量名
(2)当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个...
(3)可变个数形参的方法与本类中方法相同,形参不同的方法之间构成重载
(4)可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载,换句话说,二者不能共存
(5)可变个数形参在方法的形参中,必须声明在末尾
(6)可变个数形参在方法的形参中,最多只能一个可变形参
10.属性赋值的先后顺序
①默认初始化
②显式初始化
③构造器中赋值
④通过"对象.方法"或"对象.属性"的方法,赋值
以上操作的先后顺序:
① —— ② —— ③ —— ④
11.封装性的体现
(1)将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值
(2)不对面暴露的私有方法
(3)单例模式(将构造器私有化)
(4)如果类不希望在包外被调用,可以将类设置为缺省的
12.Java规定的四种权限符
从小到大:private < 缺省 < protected < public
4种权限都可以用来修饰类的内部结构:属性方法、构造器、内部类,修饰类的话,只能使用:缺省、public
13.构造器(或构造方法):Constructor
作用:创建对象,初始化对象的信息
使用说明:
(1)如果没显示定义类的构造器的话,则系统默认提供一个空参的构造器
(2)一个类中定义的多个构造器,彼此构成重载
(3)一个类中定义的多个构造之后,彼此构成重载
(4)一旦我们显示的定义了类的构造器之后,系统就不再提供默认的空参构造器
(5)一个类中,至少会有一个构造器
默认构造器与类权限一样
14.子类继承父类的体现
(1)一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。
特别的,父类中声明为private的属性方法,子类继承父类以后,仍然认为获取了父类中私有的结构。因为封装的影响,使得子类不能直接调用父类的结构而已。
(2)子类继承父类以后,还可以声明自己特定的属性或方法:实现功能的拓展。子类和父类的关系,不同于子集和集合的关系。
(3)extend
15.Java中继承性的说明
(1)一个类可以被多个子类继承
(2)Java中类的单继承:一个类只能有一个父类
(3)子父类是相对的概念
(4)子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
(5)子类继承父类以后,就获取了直接父类以及所间接父类中声明的属性和方法
16.什么是方法的重写(override或overwrite)?
子类继承父类以后,可以对父类同名方法,进行覆盖
重写的规则
(1)子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
(2)子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
特殊情况:子类不能重写父类中声明为private权限的方法
(3)返回值类型:
1)父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是欧弟
2)父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
3)父类被重写的方法返回值类型是基本年数据类型(比如:int),则子类重写的方法的返回值类型不许是相同的基本数据类型(也必须是int)
(4)子类重写的方法抛出异常类型不大于父类被重写的方法抛出的异常类型
(5)子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)
17.区分方法的重写和重载?
(1)两者的概念:
重写:子类继承父类以后,可以对父类同名方法,进行覆盖
重载:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。遵循:"两同一不同"(同一个类、方法名相同)
(2)规则:
重写:
(1)子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
(2)子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
特殊情况:子类不能重写父类中声明为private权限的方法
(3)返回值类型:
1)父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是欧弟
2)父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
3)父类被重写的方法返回值类型是基本年数据类型(比如:int),则子类重写的方法的返回值类型不许是相同的基本数据类型(也必须是int)
(4)子类重写的方法抛出异常类型不大于父类被重写的方法抛出的异常类型
(5)子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)
重载:"两同以不同"(同一个类、方法名相同)
(3) 重写:表现为多态性
重载:不表现为多态性
18.super:父类的
可以调用:属性、方法、构造器
super调用属性、方法:
(1)我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super"
(2)特殊情况,当子类和父类中定义可同名的属性时,我们要想在子类中调用父类中声明的属性则必须显式的
(3)特殊情况,当子类重写了父类的方法以后,想在子类的方法中调用父类中被重写的方法时,则必须显式的,
(4)使用"super.方法"的方式,表明调用的是父类中被重写的方法。
20.调用构造器
(1)我们可以在子类的构造器中显示的使用"super(形参列表)"的方式,调用父类中声明的指定构造器
(2)"super(形参列表)"的使用,必须声明在子类构造器的首行
(3)我们在构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二选一
(4)在构造器首行,没有显示的声明"this(形参列表)"或"super(形参列表)",则默认调用的是父类中无参的构造器:super()
(5)在类的多个构造器中,至少一个类的构造器中使用了"super(形参列表)",调用父类中的构造器
21.多态性
父类的引用指向子类的对象(或子类的对象赋给父类的引用)
Object obj = new Date() ;
我们在编译期,只能调用父类中声明的方法,但是在运行期我们实际执行的是子类重写父类的方法(编译看左边,执行看右边)
前提:类的继承关系,方法的重写
适用:只适用于方法,不适用于属性
22.==和equals()的区别
==:运算符
(1)可以使用在基本数据类型变量和引用数据类型变量中
(2)如果比较的是基本类型数据变量:比较两个变量保存的数据是否相等
如果比较的是引用数据类型变量:比较两个对象的地址值是否相等
equals()方法
(1)是一个方法,而非运算符
(2)只能适用于引用数据类型
(3)Object类中equals()的定义:
public boolean equals(Object obj) {
return (this == obj);
}
说明:Object类中定义的equals()和==相同的,比较两个对象的地址值是否相同,及两个引用是否指向同一块地址
(4)像String、Date、File、包装类都重写了Object类的equals()方法。重写以后比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同
(5)通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,需要对Object类equals()方法进行重写。
public class Costomer {
private String name ;
private int age ;
public Costomer() {
super();
}
public Costomer(String name, int age) {
super();
this.name = name;
this.age = age;
}
//重写规则:比价两个对象的实体内容(即:name和age是否相同)
@Override
public boolean equals(Object obj) {
if(this == obj){
return true ;
}
if(obj instanceof Costomer) {
Costomer cus = (Costomer) obj ;
//比较两个对象的每个属性是否都相同
return this.age == cus.age && this.name.equals(cus.name) ;
}
return false ;
}
}
22.toString()方法
(1)当我们输出一个对象引用的时,实际上就是调用当前对象的toString()
(2)Object类中toString()方法的使用
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
(3)x像String、Date、File、包装类等都重写了Object类中的toString()方法
例题:
String str = "abc" ;
System.out.println(str) ;//abc
System.out.println(str.toString()) ;//abc
str = null ;
System.out.println(str) ;//null
System.out.println(str.toString()) ;//NullPointerException异常
23.包装类的使用
(1)java提供的了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征
(2)基本类型、包装类、String三者之间的相互转换
24.基本类型、包装类、String之间的转化
例题1:
Object obj = true ? new Integer(1) : new Double(2.0) ;
System.out.println(o1) ;//1.0
Object obj2 ;
if(true)
o2 = new Integer(1) ;
else
o2 = new Double(2.0) ;
System.out.println(o2) ;//1
例题2:
Integer i = new Integer(1);
Integer j = newInteger(1);
System.out.println(i==j);//false
Integer m = 1 ;
Integer n = 1 ;
System.out.println(m==n);//true
//Integer定义了IntegerCache结构,IntegerCache中定义了Integer[]
//保存了从-128~127范围的整数。如果我们使用自动装箱的方式,给Integer赋值的范围在
//-128~127范围内时,可以直接使用数组中的元素,不用再去new了,以提高数组
Integer x = 128;
Integer y = 128;
System.out.println(x==y);//false
25.static关键字的使用
1.static:静态的
2.static可以用来修饰:属性、方法、代码块、内部类
3.使用static修饰属性:静态变量(或类变量)
3.1属性,按是否使用static修饰,又分为:静态属性VS非静态属性(实例变量)
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。
静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。
3.2 static修饰属性的其他说明:
1)静态变量随着类的加载而加载,可以通过"类.静态变量"的方式进行调用
2)静态变量的加载早于对象的创建
3)由于类只会加载一次,静态变量在内存中也只会存在一份:存在方法区的静态域中
4) 类变量 实例变量
类 yes no
对象 yes yes
4.使用static修饰方法:
1)静态方法随着类的加载而加载,可以通过"类.静态方法"的方式进行调用
2) 静态方法 非静态方法
类 yes no
对象 yes yes
3)静态方法中,只能调用静态的方法或属性
非静态发方法中,既可以调用非静态方法或属性,也可以调用的方法或属性
5.static注意点
在静态方法内,不能使用static关键字、super关键字
单例设计模式
所谓的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
//饿汉式:对象加载时间过长,线程安全
class Bank{
//1.私有化类的构造器、
private Bank() { }
//2.内部创建类的对象
//4.要求此对象也必须声明静态的
private static Bank instance = new Bank() ;
//3.提供一个方法,返回类的对象
public static Bank getInstance() {
return instance ;
}
}
//懒汉式:延迟对象创建,线程不安全
class Bank2{
//1.私有化类的构造器、
private Bank2() { }
//2.声明当前类对象,没有初始化
//4.要求此对象也必须声明静态的
private static Bank2 instance = null ;
//3.声明一个public、static方法,返回类的对象
public static Bank2 getInstance() {
if(instance == null) {
instance = new Bank2() ;
}
return instance ;
}
}
26.代码块
1)静态代码块
>内部可以有输出语句
>随着类的加载而执行,而且只执行一次
>如果一个类中声明了多个静态代码块,则按照声明的先后顺序执行
>静态代码块要优先于非静态代码块
>静态代码块内只能调用静态等属性\静态的方法,不能调用非静态的结构
作用:初始化类的信息
2)非静态代码块
>内部可以有输出语句
>随着对象的创建而执行
>每创建一个对象,就执行一次非静态代码块
>如果一个类中定义了多个代码块,则按照声明的先后顺序执行
>非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法
作用:可以在创建对象时,对对象的属性等进行初始化
对属性可以赋值的位置:
1)默认初始化
2)显式初始化
5)在代码块中赋值
3)构造器中初始化
4)有了对象以后,可以通过“对象,属性”或”对象,方法”的方式,进行赋值
顺序:1 -> 2/5 -> 3 -> 4
2和5谁在前谁先执行
27.final关键字
1)final可以用来修饰的结构:类、方法、变量
2)final 用来修饰一个类:此类不能被其他类所继承。比如:String类、System类、StringBuffer类
3)final用来修饰方法:表明此方法不可以被重写比如:Object类中getClass();
4)final用来修饰变量:此时的"变量"就称为常量
(1)final修饰属性:可以考虑赋值的位置有:显式初始化、代码块中初始化、构造器中初始化
(2)尤其是使用fina1管饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。
一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。
28.abstract关键字
1)abstract:抽象的
2.abstract可以用来修饰的结构:类、方法
3)abstract修饰类:抽象类
(1)此类不能实例化
(2)抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)>开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
4)abstract修饰方法:抽象方法
(1)抽象方法只有方法的声明,没有方法体
(2)包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
(3)若子类重写了父类中的所有的抽象方法后,此子类方可实例化
若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
5)注意点
(1)abstract不能用来修饰:属性、构造器等结构
(2)abstract不能用来修饰私有方法、静态方法、final的方法、final的类
29.接口
1)接口使用interface来定义
2)Java中,接口和类是并列的两个结构
3)如何定义接口:定义接口中的成员
3.1 JDK7及以前:只能定义全局常量和抽象方法
>全局常量:public static final的.但是书写时,可以省略不写
>抽象方法:public abstract的
3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
//静态方法
public static void method1(){
System.out.println("CompareA:北京");}
//默认方法
public default void method2(){System.out.println("CompareA:上海");default void method3(){
System.out.println("CompareA:上海");
>接口中定义的静态方法,只能通过接口来调用
>通过实现类的对象,可以调用接口汇总的默认方法;如果实现类重写了接口中的方法,调用时,仍然调用的是重写的方法
>如果子类(或实现类)继承的父类和实现的接口声明中声明了同名同参数的方法
那么子类在没有重写此方法的情况下,默认调用的是父类同名同参数的方法。-->类优先原则
>如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,//那么在实现类没有重写此方法的情况下,报错。-->接口冲突。
这就需要我们必须在重现类中重写此方法
>如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
method3();//调用自己定义的重写的方法
super.method3();//调用的是父类中声明的
//调用接口中的默认方法
CompareA.super.method3();
CompareB.super.method3();
4)接口中不能定义构造器的!意味着接口不可以实例化
5)Java开发中,接口通让类去实现(implements)的方式来使用
(1)如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
(2)如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
6)Java类可以实现多个接口--->弥补了Java单继承性的局限性格式:class AA extends BB implements CC,DD,EE
7)接口与接口之间可以继承,而且可以多继承
8)接口的具体使用,体现了多态性
30.抽象类和接口有哪些共同点和区别
相同点:不能实例化,都可以继承
不同点:抽象类:有构造器,单继承。接口:不能声明构造器,多继承,JDK7以前只能有全局常量和抽象方法,
JDK7以后可以定义静态方法和默认方法
31.内部类
1)Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
2)内部类的分类:成员内部类(静态、非静态)VS局部内部类(方法内、代码块内、构造器内)
3)成员内部类:
一方面,作为外部类的成员:
>调用外部类的结构
>可以被static修饰
>可以被4种不同的权限修饰
另一方面,作为一个类:
>类内可以定义属性、方法、构造器等
>可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
>可以被abstract修饰
4)如何实例化成员内部类的对象
//创建Dog实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();dog.show();
//创建Bird实例(非静态的成员内部类):
//Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person,Bird bird=p.new Bird();
bird.sing();
5)内部类区分调用外部类的结构
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性