- 三条主线
- 面向过程和面向对象
- 面向对象两要素
- 类和对象的使用
- 属性与局部变量的对比
- 类方法的声明和使用
- return关键字的使用
- 匿名对象的使用
- 方法重载(Overload)
- 可变个数形参的方法
- 变量赋值
- 值传递机制
- 递归方法
- 封装与隐藏
- 构造器
- 属性赋值的先后顺序
- JavaBean
- this关键字
- package关键字的使用
- import关键字的使用
- eclipse快捷键
- 继承性
- object类
- 方法的重写(Override)
- super关键字
- 子类对象实例化
- 多态性
- 向下转型
- instanceof关键字的使用
- ==运算符
- equals()方法
- JUnit单元测试
- 包装类(wrapper)
- static关键字
- 单例设计模式
- main()方法的使用说明
- 代码块
- final(最终的)
- abstract关键字
- 匿名对象
- 接口的使用
- 创建接口匿名实现类的对象
- Java8接口新特性
- 内部类
三条主线
1.Java类及类的成员:属性、方法、构造器;代码块、内部类
2.面向对象的三大特征:封装性、继承性、多态性、(抽象性)
3.其他关键字:this、super、static、final、abstract、interface、package、import
面向过程和面向对象
面向过程:强调的功能行为,以函数为最小单位,考虑怎么做
例:人把大象装冰箱
1.把冰箱门打开
2.抬起大象,塞进冰箱
3.把冰箱门关闭
面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做
例:人把大象装冰箱
人{
打开(冰箱){
冰箱.开开();
}
}
冰箱{
打开(){}
闭合(){}
}
大象{
进入(冰箱){
}
}
面向对象两要素
类:对一类事物的描述,是抽象的、概念上的定义
对象:是实际存在的该类事物的每个个体
>面向对象程序设计的重点是类的设计
>设计类,就是设计类的成员
1.属性=成员变量=field=域、字段
2.方法=成员变量=函数=method
类和对象的使用
1.创建类,设计类的成员(最重要)
2.创建类的对象
3.通过“对象.属性”或“对象.方法”调用对象
//类和对象的创建
class Person{
//属性
String name;
int age=1;
boolean isMale;
//方法
public void eat(){
System.out.println("人可以吃饭");
}
public void sleep(){
System.out.println("人可以睡觉");
}
public void talk(String language){
System.out.println("人可以说话,使用的是:"+language);
}
}
//测试类
public class PersonTest{
public static void main(String[] age){
//创建类的对象
Person p1=new Person();
调用对象的结构:属性、方法
//调用属性:对象名.属性
p1.name="Tom";
p2.isMale=true;
//调用方法:对象名.方法
p1.eat();
p1.sleep();
p1.talk("Chinese");
}
}
对象在什么条件下成为垃圾?什么情况下释放垃圾对象,如何证明一个对象被释放了?
当一个对象有多个引用时,若所有引用都变成null时,对象没有任何引用,成为垃圾。成为垃圾后,系统不会自动释放对象所占内存资源,而是在资源不够情况下才进行释放。对象不再占有内存空间时说明对象被释放了。
属性与局部变量的对比
相同点
1.定义变量的格式:数据类型 变量名=变量值
2.先声明,后使用
3.变量都有其对应的作用域
不同点
1.在类中声明位置不同
属性:直接定义在类的一对{}内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
2.权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符
常用的权限修饰符:private、public、protected、缺省
局部变量:不可以使用权限修饰符
3.默认初始化值
属性:类的属性,根据其类型,都有默认初始化值
>整型:0
>浮点型:0.0
>char型:0或’\u0000’,而非’0’
>boolean型:false
>引用数据类型:null
局部变量:没有默认初始化值
意味着我们在调用局部变量之前,一定要显示赋值
4.在内存中加载的位置
属性:加载到堆空间中(非static)
局部变量:加载到栈空间
类方法的声明和使用
方法:描述应该具有的功能
比如:Math类:sqrt()\random()...
Scanner类:nextXxx()…
Arrays类:sort()\binarySearch()\toString()\equals90...
举例:
public void eat(){}
public void sleep(int hour){}
public String getName(){}
public String getNation(String nation){}
方法的声明:
权限修饰符 返回值类型 方法名(形参列表){
方法体
}
例:
public void runing(String run){
System.out.println("我现在在"+run);
}
返回值类型
有返回值:
如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用return关键字来返回指定类型的变量或常量:“return 数据”
没返回值:
如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不使用return,但,如果使用的话,只能“return;”表示结束此方法的意思
return关键字的使用
使用范围:使用在方法体中
作用:
1.结束方法
2.针对于有返回值类型的方法,使用”return数据“方法返回所要的数据
注:return关键字后面不可以声明执行语句
匿名对象的使用
1.理解:创建的对象,没有显示的赋给一个变量名。即为匿名对象
2.特征:只能调用一次
3.使用:
PhoneMall mall=new PhoneMall();
//匿名对象使用
mall.show(new Phone());
class PhoneMall{
public void show(Phone phone){
phone.sendEmail();
phone.playGame();
}
}
方法重载(Overload)
1.定义:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可
“两同一不同”:同一个类、相同方法名
参数列表不同:参数个数不同、参数类型不同
2.举例:
Array类中重载的sort()/binary Search()
3.判断是否是重载:
跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系
4.在通过对象调用方法时,如何确定某一个指定的方法:
方法名—->参数列表
可变个数形参的方法
具体使用:
1.格式:数据类型…变量名
例:public void show(String…str);
2.当调用可变个数形参的方法时,传入的参数个数可以是0、1、2…
3.可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
4.可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间构不成重载
5.可变个数形参在方法的形参中,必须声明在末尾
6.可变个数形参在方法的形参中,最多声明一个
变量赋值
1.变量为基本数据类型,此时赋值的是变量所保存的数据值
2.变量为引用数据类型,此时赋值的是变量所保存的数据的地址值
值传递机制
1.形参:方法定义时,声明的小括号内的参数
实参:方法调用时,实际传递给形参的数据
2.值传递机制:
如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值
如果参数是引用类数据类型,此时实参赋给形参的是实参真实存储的数据地址值
递归方法
1.递归方法:一个方法体内调用它自身
2.方法递归包含了一种隐式的循环,他会重复执行某段代码,但这种重复执行无须循环控制
注:递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环
例:
public int getSum(int n){
if(n==1){
return 1 { //计算1-n之间所有自然数的乘积
}else{
return n+getSum(n-1);
}
}
}
封装与隐藏
问题的引入
当我们创建一个类的对象后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。这里赋值操作要受到属性的数据类型和储存范围的制约。除此之外,没有其他制约条件。但是,在实际问题中,我们往往需要给属性赋值加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。同时,我们需要避免用户再使用“对象.属性”的方法对属性进行赋值。则需要将属性声明为私有的(private)—>此时,针对于属性就体现了封装性
封装性的体现
我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getxxx)和设置(setxxx)此属性的值
public int getAge(){
return age;
}
public void setAge(int a){
age=a;
}
拓展:封装性的体现:1.不对外暴漏的私有方法2.单例模式
封装性的体现,需要权限修饰符来配合
Java四种权限:private、缺省、protected、public
使用:private int orderPrivate(出了类所属的包后,私有的结构、缺省声明的结构就不可以调用了)
int orderDefault
public int orderPublic
四种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
修饰类的话只能使用:缺省、public
总结封装性:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可用性的大小
构造器
1.构造器的作用:创建对象
创建类的对象:new+构造器
2.说明:
1.如果没有显式的定义构造器的话,则系统默认提供一个空参的构造器
2.定义构造器的格式:权限修饰符 类名(形参列表){}
3.一个类中定义多个构造器,彼此构成重载
4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
5.一个类中,至少会有一个构造器
注:首先,构造器是不能被继承的,因为每个类的类名都不相同,而构造器名称与类名相同,所以根本谈不上继承。
又由于构造器不能继承,所以就不能被重写。但是,在同一个类中,构造器是可以被重载的。
构造器调用顺序
1)new StackArray()即无参的实例化过程:
找到无参构造器 > 初始化成员变量(引用类型初始化为null,int初始化为0) > this(10)调用有参构造器 > 来到有参构造器并初始化赋值形参(initialSize=10)> 成员变量赋值(例如top=-1)> 执行有参构造器内部代码(输出了“有参构造器执行”)> 执行无参构造器内部代码(输出了“无参构造器执行”)> 结束
2)new StackArray(20)有参的实例化过程:
找到有参构造器 > 初始化赋值形参并初始化成员变量(引用类型初始化为null,int初始化为0) > 成员变量赋值(例如top=-1)> 执行有参构造器内部的代码 > 结束
3)如果无参构造器内没有调用有参构造器,new StackArray()的实例化过程:
找到无参构造器 > 初始化成员变量(引用类型初始化为null,int初始化为0) > 成员变量赋值(例如top=-1)> 执行无参构造器内部代码(输出了“无参构造器执行”)> 结束
属性赋值的先后顺序
1.默认初始化
2.显式初始化
3.构造器中赋值
4.通过“对象.方法”或“对象.属性”的方式赋值
JavaBean
是一种Java语言写成的可重用组件
JavaBean是指符合如下标准的Java类
1.类是公共的
2.有一个无参的公共的构造器
3.有属性,且有对应的get、set方法
this关键字
this修饰属性和方法
this理解为:当前对象或正在创建的对象
1.在类方法中,我们可以使用“this.方法”的方式调用当前对象属性或方法。但是通常情况下,我们都选择省略“this.”。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用“this.变量”的方式,表明此变量是属性,而非形参
2.在类的构造器中,我们可以使用“this.属性”或“this.方法”的方式,调用当前正在创建的对象属性或方法。但是,通常情况下,我们都选择省略“this.”。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式的使用“this.变量”的方式,表明此变量是属性,而非形参
this调用构造器
1.显式的使用“this(形参列表)”方式,调用本类中指定的其他构造器
2.构造器中不能通过“this(形参列表)”方式调用自己
3.如果一个类中有n个构造器,则最多有n-1个构造器中使用了“this(形参列表)”
4.规定:“this(形参列表)”必须声明在当前构造器的首行
5.构造器内部,最多只能声明一个“this(形参列表)”,用来调用其他的构造器
package关键字的使用
1.为了更好的实现项目中类的管理,提供包的概念
2.使用package声明类或接口所属的包,声明在源文件的首行
3.包,属于标识符,遵循标识符的命名规则、规范(xxxyyyyzzz)、见名知意
4.每“.”一次,就代表一层文件目录
补:同一个包下,不能命名同名的接口、类
不同的包下,可以命名同名的接口、类
import关键字的使用
import:导入
1.在源文件中显式的使用import结构导入指定包下的类、接口
2.声明在包的声明和类的声明之间
3.如果需要导入多个结构,则并列写出即可
4.如果使用“xxx.”的方式,表示可以导入xxx包下的所有结构
5.如果使用类或接口是Java.lang包下定义的,则可以省略import结构
6.如果使用的类或接口是本包下定义的,则可以省略import结构
7.如果在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显示
8.使用“xxx.”方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入
9.import static:导入指定类或接口中的静态结构
eclipse快捷键
继承性
好处:1.减少了代码的沉于,提高了代码的复用性
2.便于功能的拓展
3.为之后多态性的使用,提供了前提
格式:class A extend B{}
extends:延展、扩展
A:子类、派生类、subclass
B:父类、超类、基类、superclass
体现:1.一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有属性和方法。特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。只因为封装性的影响,使得子类不能直接调用父类的结构而已
2.子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展
子类和父类的关系不同于子集和集合的关系
规定:1.一个类可以被多个子类继承
2.类的单继承性:一个类只能有一个父类
3.子父类是相对概念
4.子类直接继承的父类称为:直接父类,间接继承的父类称为:间接父类
5.子类继承父类以后,就获取了直接父类以及所有简介父类中声明的属性方法
object类
1.如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.object类
2.所有java类(除java.lang.object类外)都直接或间接的继承于java.lang.object类
3.所有java类具有java.lang.object类声明的功能
方法的重写(Override)
重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作
应用:重写以后,当创建子类对象以后,通过子类对象调用子父对象调用子父类中的同名同参数的方法时,执行的是子类重写父类的方法
规定:
方法的声明:权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{
}
约定俗成:子类中的叫重写的方法,父类的叫被重写的方法
1.子类重写的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
2.子类重写的方法的权限修饰符不小于父类被重写的方法权限修饰符
特殊:子类不能重写父类中声明为private权限的方法
3.返回值类型
父类被被重写的方法的返回值类型是void,则子类重写的方法返回值类型只能是void
父类被被重写的方法的返回值类型是A类型,,则子类重写方法的返回值可以是A类型或A类型的子类
*父类被被重写的方法的返回值类型是基本数据类型(比如:double)则子类重写的返回值类型必须是相同类型(double)
4.子类重写的方法抛出的异常类型不大于被重写的方法抛出的异常类型
5.子类和父类中的同名同参的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)
super关键字
使用
1.我们可以在子类方法或构造器中。通过使用“super.属性”或“super.方法”的方式,显式的调用父类中声明属性或方法。但是,通常情况下,我们习惯省略“super”
2.特殊情况,当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须是显式的使用“super.属性”的方法,表明调用的是父类中声明的属性
3.特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用“super.方法”,表明调用的是父类中被重写的方法
super调用构造器
1.我们可以在子类的构造器中显式的使用“super(形参列表)”的方式,调用父类中声明的指定的构造器
2.“super(形参列表)”的使用,必须声明在子类构造器的首行
3.类的构造器中,“this(形参列表)”和“super(形参列表)”二者只能出现一个
4.在构造器的首行,没有显式的声明“super(形参列表)”或“this(形参列表)”,则默认调用的是父类中空参的构造器:super()
5.在类的多个构造器中,至少有一个类的构造器中使用了“super(形参列表)”,调用父类中的构造器
子类对象实例化
1.从结果上来看
子类继承父类以后,就获取了父类中声明的属性或方法
2.从过程上来看
当我们通过子类的构造器创建对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类构造器,直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才能看到内存中有父类的结构,子类对象才可以考虑进行调用
明确:虽然创建子类对象时,调用了父类构造器,但是自始至终就创建过一个对象,即为new的子类对象
多态性
理解:可以理解为一个事物的多种形态
何为多态性:对象的多态性:父类的引用指向子类的对象
使用:虚拟方法调用
有了对象多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们执行的是子类重写父类的方法
总结:编译看左边,运行看右边
使用前提:1.类的继承关系2.方法的重写
注:对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)
向下转型
使用情景:有了对象多态性以后,内存中实际上是加载了子类特有的属性和方法的,但由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用
向下转型:使用强制类型转换符
例:Man m1=(Man)p2;
m1.earnMoney();
使用强转时,可能出现ClassCastException的异常
例:Woman w1=(Woman)p2;
w1.goShopping();
instanceof关键字的使用
a instanceof A:判断对象a是否是类A的实例。如果是,返回true,如果不是,返回false
例:if(p2 instanceof Man){
Man m2=(Man)p2;
m2.earnMoney();
System.out.println(“**Man*“);
}
使用情景:为了避免在向下转型时出现ClassCastException的异常,
我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型
注:如果a instanceof A返回true,且a instanceof B也返回true,其中,类B是类A的父类
==运算符
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()进行重写
重写原则:比较两个对象的实体内容是否相同
JUnit单元测试
步骤:1.选中当前工程- 右键选择:build path- add libraries- JUnit 4- 下一步
2.创建Java类,进行单元测试
此时的Java类要求:1.此类是public的 2.此类提供公共的无参的构造器
3.此类中声明单元测试方法
此时的单元测试方法:方法的权限是public,没有返回值,没有形参
4.此单元测试方法上需要声明注解:@Test,并在单元测试类中导入:import org.junit.Test;
5.声明好单元测试方法以后,就可以在方法体内测试相关的代码
6.写完代码以后,左键双击单元测试方法名,右键:run as- JUnit Test
说明:
1.如果执行结果没有异常:绿条
2.如果执行结果出现异常:红条
包装类(wrapper)
自动装箱
基本数据类型—->包装类
例:
int num2=1;
Integer in1=num2;
自动拆箱
包装类—->基本数据类型
例:
System.out.println(in1.toString());
int num3=in1;
基本数据类型、包装类—->String类型
调用String的valueOf
例:
float f1=12.3f;
String str1=String.valueOf(f1); 输出: “12.3”
String类型—->基本数据类型、包装类
调用包装类的parseXxx()
例:
String str1=”123”;
int num2=Integer.parseInt(str1);
System.out.println(num2); 输出:123
static关键字
static:静态的
static可以用来修饰:属性、方法、内部类
使用static修饰属性:静态变量(或类变量)
1.属性按是否使用static修饰,又分为:静态属性和非静态属性(实例变量)
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修饰其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改
静态变量:我们创建了类的多个对象共享同一个静态变量,当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过的
2.static修饰属性的其他说明
1.静态变量随着类的加载而加载
2.静态变量的加载要早于对象的创建
3.由于类只会加载一次,则静态变量在内存中也只会存在一份,存在方法区的静态域中
3. 类变量 实例变量
类 yes no
对象 yes yes
4.使用static修饰方法:静态方法
1.随着类的加载而加载,可以通过”类.静态方法“的方式进行调用
2. 静态方法 非静态方法
类 yes no
对象 yes yes
3.静态方法中,只能调用静态方法或属性
非静态方法中,既可以调用非静态方法或属性,也可以调用静态的方法或属性
5.注意:在静态的方法内,不能使用this关键字、super关键字
关于静态属性的静态方法的使用,大家都从生命周期的角度去理解
6.开发中,如何确定一个属性是否要声明为static
属性是可以被多个对象所共享的,不会随着对象的不同而不同
开发中,如何确定一个方法是否要声明为static
操作静态属性的方法,通常设置为static
*工具类中的方法,习惯上声明为static的。如:Math、Arrays、Collections
单例设计模式
1.所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例
2.如何实现
饿汉式
class Bank{
//私有化类的构造器
private Bank(){
}
//内部创建类的对象
//要求此对象也必须声明为静态
private static Bank instance = new Bank();
//提供公共的静态的方法,返回类的对象
public static Bank getInstance(){
return instance;
}
}
懒汉式
class Order{
//私有化类的构造器
private Order(){
}
//声明当前类对象,没有初始化
//要求此对象也必须声明为静态
private static Order instance =null;
//提供公共的静态的方法,返回类的对象
public static Order getInstance(){
if(instance==null ){
instance=new Order();
}
return instance;
}
饿汉式与懒汉式的区别
饿汉式:
好处:线程是安全的
坏处:对象加载时间过长
懒汉式:
好处:延迟对象的创建
坏处:线程不安全,要修改
main()方法的使用说明
1.main()方法作为程序的入口
2.main()方法也是一个普通的静态方法
3.main()方法可以作为我们与控制台交互的方式(之前使用Scanner)
代码块
1.作用:用来初始化类、对象
2.代码块如果有修饰的话,只能使用static
3.分类:静态代码块和非静态代码块
4.静态代码块
内部可以有输出语句
随着类的加载而执行,而且只执行一次
作用:初始化类的信息
如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
静态代码块的执行要优先于非静态代码块的执行
静态代码块内只能调用静态属性、静态方法,不能调用非静态的结构
5.非静态代码块
内部可以有输出语句
随着对象的创建而执行
每创建一个对象,就执行一次非静态代码块
作用:可以在创建对象时,对对象的属性等进行初始化
如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
非静态代码块内可以调用静态的方法、静态的属性,或非静态的属性、非静态的方法
对属性可以赋值的位置
1.默认初始化
2.显示初始化
3.构造器中初始化
4.有了对象以后,可以通过“对象.属性”或“对象.方法”的方式进行赋值
5.在代码块中赋值
顺序:1 - 2/5 - 3 - 4
final(最终的)
1.final修饰类:此类不能被其他类所继承
2.final修饰方法:表明此方法不可以被重写
比如:Object类中getClass();
3.final修饰变量:此时的“变量”就称为一个常量
final修饰属性,可以考虑赋值的位置有:显示初始化、代码块中初始化、构造器中初始化
final修饰局部变量:尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参,一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值
static final修饰:全局变量
abstract关键字
1.abstract:抽象的
2.abstract可以用来修饰的结构:类、方法
3.abstract修饰类:抽象类
此类不能实例化
抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
4.abstract修饰方法:抽象方法
抽象方法只有方法的声明,没有方法体
包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的
若子类重写了父类中的所有的抽象方法后,此子类方可实例化
若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract
注:abstract不能用来修饰:属性、构造器、私有方法、静态方法、final的方法、final的类
匿名对象
接口的使用
1.接口使用interface来定义
2.Java中,接口和类是并列的两个结构
3.如何定义接口,定义接口中的成员
1.jdk7以前:只能定义全局常量和抽象方法
全局常量:public static final (书写时可以省略)
抽象方法:public abstract
2.jdk8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
4.接口中不能定义构造器。意味着接口不可以实例化
5.Java开发中,接口通过让类去实现(implements)的方法来使用
如果实现覆盖了接口中所有抽象方法,则此实现类就可以实例化
如果实现没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
6.Java类可以实现多个接口—->弥补了Java单继承性的局限性
格式:class AA extends BB implements CC,DD,EE
7.接口与接口之间可以继承,而且可以多继承
8.接口的具体使用,体现多态性
9.接口可以看做是一种规范
创建接口匿名实现类的对象
Java8接口新特性
1.接口中定义的静态方法,只能通过接口来调用
2.通过实现类的对象,可以调用接口中的默认方法。如果实现类重写了接口中默认方法,调用时,仍然调用的是重写以后的方法
3.如果子类(或实现类)继承的父类和实现的接口中声明了同名同参的默认方法,那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。—->类优先原则
4.如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下,报错。—->接口冲突
这就需要我们必须在实现类中重写此方法
内部类
1.Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
2.内部类的分类:成员内部类(静态、非静态)、局部内部类(方法内、代码块内、构造器内)
3.成员内部类:
一方面,作为外部类的成员
调用外部类的结构
可以被static修饰
可以被4种不同的权限修饰
另一方面,作为一个类
类内可以定义属性、方法、构造器等
可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
可以被abstract修饰