一、Java 方法
概念:具有特殊功能的一段代码,将需要在多个位置重复使用的一段代码定义在类内部;
意义:避免了重复的代码、增强了程序的扩展性;
(一)、定义方法(语法格式):
方法名称定义规范:尽量见名知义、驼峰命名法、动宾结合
[ 修饰符 ] 方法返回值的类型 方法的名称(形参1,形参2...)
{
方法体
[return 值]; // 若方法需要给调用者返回一个结果,此时使用 return 值。
}
(二)、方法调用:
方法必须要调用才能生效;
(1)、如果方法使用了 static 修饰:
此时我们使用方法所在类的名称.方法名(参数);
类名.方法名();
(2)、如果方法没有使用 static 修饰:
此时我们得使用方法所在类的对象来调用;
类名 对象名 = new 类名();
对象.方法名();
(三)、方法返回值-- return 关键字
如果一个方法没有返回值,那么修饰符为 void;
注意点:
1、如果一个方法有返回值,那么需要写 return 返回值。
2、定义方法时声明的返回值类型,要和 return 后实际上返回的数值类型一致;
3、一个方法声明了有返回值,若该方法中有分支语句或循环语句,那么要保证无论执行哪个分支,都要有 return 可以被执行;
4、如果一个方法声明没有返回值,那么方法中可以使用 return 语句,强行结束方法;
(四)、方法之间的相互调用;
方法之间是可以相互调用的;
(五)、方法的参数
一个方法中,有些数据的数值不确定,我们定义为参数;由调用处调用方法的时候,传入具体的数字;
形式参数:形参
定义方式:声明的参数,用于接收调用处传来的数值;
实际参数:实参
调用方法的时候,实际赋值给形参的数据;
(六)、方法的分类
有返回值:
有参数有返回值:public static 返回值类型 方法名(形参列表){}
无参数有返回值:public static 返回值类型 方法名(){}
无返回值:
有参数无返回值:public static void 方法名(形参列表){}
无参数无返回值:public static void 方法名(){}
(七)、方法重载
概念:一个方法,因为参数不同,执行的具体方法也不同;
一个方法的多种形式;
同一个类中;方法名相同;参数列表不同(参数个数、参数顺序、参数类型);
与 static、返回值类型,其他的修饰符 都无关;
规则:
1、同一个类中;
2、方法名必须相同;
3、参数列表必须不同:参数的顺序、参数的个数、参数的类型;
(八)、递归
方法中调用方法本身,叫做递归方法;
递归一定要有出口,否则会造成死循环;
public class Recursion_Demo {
public static void test1(int num){
System.out.println("test1..."+num);
if (num == 1){
return; // 方法的出口
}
test1(num - 1);
}
public static void main(String[] args) {
test1(5);
}
}
二、面向对象思想概述
(一)、类和对象
类:是一组相关属性和行为的结合,可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物;
属性:就是该类事物的状态信息;
行为:就是该事物能够做什么;
对象:是一类事物的具体体现,对象是类的一个实例,必然具备该类事物的属性和行为;
类与对象的关系:
类是对一类事物的描述,是 抽象的;
对象是一类事物的实例,是 具体的;
类是对象的模板,对象是类的实体;
(二)、类的定义
[修饰符] class 类名{
//1、属性字段:Filed
成员变量
//2、成员方法:Method
行为功能
//3、构造方法:Construction
}
注意点:
类中的成员变量的默认值 :
基本类型:int、byte、short、long、float、double,默认值都是 0;
boolean 的默认值为: false;
char 的默认值是空字符;
引用类型,默认值都为 null;
(三)、构造函数
构造方法是一种特殊的方法;
1、定义的语法结构不同
[访问权限修饰符] 方法名(参数列表){
}
修饰符:访问权限修饰符;
没有返回值类型,也不写 void;
方法名,必须和类名一致;
参数:
没有参数,无参构造;
有参数列表,有参构造;
2、调用
在 new 新对象的时候,就在调用构造方法;
(四)、this 关键字
this 代表所在类的当前对象的引用(地址值),及对象自己的引用;
方法被哪个对象调用,方法中的 this 就代表哪个对象,即谁在调用,this 就代表谁;
1、指代本类的对象,可以访问本类的属性和方法;
用途1:当局部变量和成员变量冲突的时候,通过 this 来区分;
public Person_Demo(String name,int age){
this.name = name;
this.age = age;
}
用途2:访问本类的属性和方法;
public void study(){
System.out.println(this.name+"在学习...");
}
public void work(){
this.study();
System.out.println("去工作...");
}
2、指代构造方法:this();
如果存在多个构造方法 那么 this 指代的构造方法要靠参数来区分:顺序,个数,类型;
注意:this 执行构造函数的时候,只能放在第一句;
public Person_Demo(){
this("李连杰",68);
}
public Person_Demo(String name,int age){
this.name = name;
this.age = age;
}
三、面向对象三大特性之封装性
面向对象有三大特性:封装、继承、多态
封装性:尽可能隐藏对象的内部实现细节,控制对象的修改及访问的权限;
1、隐藏了实现的细节;
2、提高了代码的复用性;
3、提高了安全性、保护细节、保护数据的安全;
封装步骤:
1、使用权限修饰符来修饰属性,限于本来中访问(private);
2、因为对象对属性的操作:设值 和 取值
我们在类中提供两个方法,分别用于给属性设值 和 取值;
设值方法:settler:setXXX(),例如:serAge();
取值方法:getter:getXXX(),例如:getAge();
访问权限修饰符有 4 个:
private:私有的,表示类访问权限,只能在本类中访问,离开本类之后,就不能直接访问;
不写(缺省):包私有,表示包访问权限,访问者的包必须和当前定义类的包相同才能访问;
protected:子类访问权限,同包中的可以访问,即使不同包,但是有继承关系,也可以访问;
public:表示公共访问权限,若某一个字段或者方法使用了 public 修饰,则可以在当前项目中任何地方进行访问。(类也需要是 public 修饰的)
修饰符 | 类内部 | 同一个包 | 子类 | 任何地方 |
private | ✔ | |||
无(缺省) | ✔ | ✔ | ||
protected | ✔ | ✔ | ✔ | |
public | ✔ | ✔ | ✔ | ✔ |
四、static 关键字
静态成员是全类所有对象共享的成员
(一)、静态属性(类属性)
(二)、静态方法(类方法)
static 关键字修饰方法的时候形成静态方法,此时方法属于类不再属于对象了,应该用类来访问,但是对象也可以访问。
在静态方法中,不能直接访问成员变量、不能直接访问成员方法、可以访问类属性(静态属性)、可以访问静态的方法;
(三)、静态代码块
用 static 关键字修饰的代码块;
1、在 mian 方法之前就执行;
2、只运行一次;
构造代码块,直接写在类里面、方法外面的代码块;
创建对象的时候,随着构造函数的调用而执行,而且优先于构造函数执行;
构造函数被多次调用,那么构造代码块也被多次调用;
普通代码块,{} 包裹起来的一段代码,需要注意作用域,随着 }的结束而结束;
优先级别:静态代码块 > 构造代码块 > 普通代码块
五、面向对象三大特性之继承
(一)、概念
描述两个类的关系的;
在 Java 中,类的继承是指在一个现有类的基础之上去构建一个新的类,构建出来的新类称作子类(派生类),现有类被称作父类(超类),子类会自动拥有父类所有非私有的属性和方法;
意义:
1、避免重复的代码(从子类角度);
2、扩展类的功能(从父类角度);
继承性:子类、父类,存在继承关系;
1、子类对象,可以直接访问父类的非私有的属性和方法;(避免代码重复)
2、子类也可以新增自己的属性和方法;(扩展类的功能)
3、子类可以重新实现父类已有的方法;(扩展类的功能)
(二)、语法
父类:A 类
子类:B 类
语法结构: class 父类 { } class 子类 extends 父类 { }
extends 关键字: 表示两个类是继承关系;
(三)、继承中的构造语法
子类在创建对象的时候,会默认调用父类的无参构造函数;
若显示调用了父类的有参构造函数,就不会调用父类的无参构造函数;
(四)、super 关键字
可以访问父类的属性;
可以访问父类的方法;
注意:this 执行构造函数的时候,只能放在第一句;
this、super 关键字不能出现在 static 方法中;
(五)、方法重写(重点)
关键字:Override
观念:继承关系中,子类将父类已有的方法重新实现,叫做方法的重写;
规则:
1、在继承关系中;
2、子类重写的方法的声明,必须和父类一致;
方法的返回值(子类重写方法的返回类型可以是父类方法返回类型的子类)、参数列表、方法名;
3、子类重写方法的访问权限,不能比父类更加严格;
4、重写的方法,不能抛出比父类更大的异常;
六、访问修饰符
访问权限:对类、方法、变量、常量等访问位置的限定,通过访问权限修饰符来实现;
在 Java 中,可以在类、类的属性集类的方法前面加上一个修饰符,来对类进行一些访问上的控制;
private:私有的,限制在本类中才能访问;
default:什么都不写,就是 default,同类、同包;
protected:受保护的,同类、同包,不同包(限于子类访问);
public:公共的,同类、同包、不同包;
修饰符 | 类内部 | 同一个包 | 子类 | 任何地方 |
private | ✔ | |||
无(缺省) | ✔ | ✔ | ||
protected | ✔ | ✔ | ✔ | |
public | ✔ | ✔ | ✔ | ✔ |
七、final 关键字
词意:最终的、终结的、最后的;
final 可修饰的内容:
类(最终类)
方法(最终方法)
变量(最终变量)
final 修饰类,此类不能被继承;
final 修饰方法,此方法不能被覆盖,意为最终方法,不支持予以覆盖的形式修改;
final 修饰变量,此变量值不能被改变(常量),所有 final 修饰的变量只能赋值一次,值不允许改变;
final 修饰基本类型,值不可变;
final 修饰引用类型,地址不可变;
静态常量不再提供默认值,必须手动赋予初始值;(public static final PI = 3.1415;)
八、多态
(一)、概念
多态是继继承、封装之后,面向对象的第三大特性;
多态(多种形态)是同一个行为具有多个不同表现形式或形态的能力,多态就是同一个接口,使用不同的实例而执行不同操作;
格式:父类类名 变量名 = new 子类对象();
调用顺序:
当使用多态调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;
如果有,再去调用子类的重写方法;
调用多态好处:
可以使程序有良好的扩展,并可以对所有类的对象进行通用处理;
(二)、引用类型转换
1、父子之间的转换分为 “向上转换 和 向下转换”,它们区别如下:
向上转换:通过子类对象(小范围)实例化父类对象(大范围),这种属于自动转换;
对象的向上转型(安全的),会失去子类新增;
子类对象被看做了父类的类型,那么就不能访问子类的新增,只能访问父类的属性和方法,以及子类重写;
向下转换:通过父类对象(大范围)实例化子类对象(小范围),属于强制转换;
为什么要转型:
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;也就是说,不能调用子类拥有,而父类没有的方法;
2、instanceof 关键字
在 Java 中,向下转换是为了通过父类强制转换为子类,从而来调用子类独有的方法;为了保证向下转型的顺利完成,在 Java 中提供了一个关键字 instanceof,通过 instanceof 可以判断某对象是否是某类的实例,如果是返回 true,否则为 false;
instanceof:判断某个对象是否是某个类的实例,类以及继承的父类;
public class TestAnimal {
public static void show(Animal animal){
animal.run();
}
public static void main(String[] args) {
Animal a = new Animal();
System.out.println("------");
Animal c = new Cat();
System.out.println("------");
Animal d = new Dog();
if(a instanceof Animal){
System.out.println("a is_a Anlmal");
}
if (c instanceof Cat){
System.out.println("c is_a Cat");
}
if (d instanceof Dog){
System.out.println("d is_a Dog");
}
}
}
九、Object 类
(一)、概述
所有的类,都是以继承结构存在的;
如果没有显示的父类,都是默认继承 Objecet 类;
Object 为超类、基类,所有类的直接或间接父类,位于继承树的最顶层;
Object 类中所定义的方法,是所有对象都具备的方法;
Object 类型可以存储任何对象;
作为参数,可接受任何对象;
作为返回值,可返回任何对象;
(二)、常用方法
getClass()
返回引用中存储的实际对象类型;
应用:通常用于判断两个引用中实际存储对象类型是否一致;
hashCode()
返回该对象的十进制哈希码值;
哈希算法根据对象的地址或字符串或数字计算出 int 类型的数值;
toString()
返回该类型的字符串表示(表现形式);
可以根据程序需求覆盖该方法,例如:展示对象各个属性值;
equals()
public boolean equals(Object obj){...}
默认实现为(this == obj),比较两个对象地址是否相同;
可进行覆盖,比较两个对象的内容是否相同;
equals 重写步骤:
比较两个引用是否指向同一个对象;
判断 obj 是否为 null;
判断两个引用指向的实际对象类型是否一致;
强制类型转换;
依次比较各个属性值是否相等;
finalize()
当对象被判定为垃圾对象时 由 JVM 自动调用此方法 用以标记垃圾对象 进入回收队列;
垃圾对象:没有有效引用指向此对象时,为垃圾对象;
垃圾回收:由 GC 销毁垃圾对象,释放数据存储空间;
自动回收机制:JVM 内存耗尽,一次性回收所有垃圾对象;
手动回收机制:使用 System.gc();通知 JVM 执行垃圾回收;
十、抽象类
(一)、抽象类与抽象方法的定义
将子类的共通特征进行抽取,抽象成一个父类,如果有的功能在父类中定义了,但是没有具体的实现,那么可以定位为抽象的,等待子类实现即可;
作用:
可被子类继承,提供共性属性和方法;
可声明为引用,更自然的使用多态;
1、抽象类:包含抽象方法的类
被 abstract 修饰的类,称为抽象类;
抽象类意为不够完美的类,不够具体的类;
2、抽象方法定义的格式:
public abstract 返回值类型 方法名(参数){ };
若一个类中有抽象方法,那么该类也必须定义为抽象类;
3、抽象类定义的格式:
public abstract class 类名 { };
(二)、注意事项
抽象类和抽象方法都需要被 abstract 修饰,抽象方法一定要定义在抽象类中;
抽象类不可以直接创建对象,原因:调用抽象方法没有意义;
只有覆盖了抽象类中所有的抽象方法 子类才可以创建对象 否则该子类还是一个抽象类;
之所以继承抽象类,更多的是在思想,是面对共性类型操作会更简单;
抽象类不允许被实例化,因为可能包含有抽象方法,必须等待子类来继承,并且实现抽象方法;但是如果没有全部实现,子类也是抽象类,要再等待子类来继承,并且实现抽象方法;
重要的结论:抽象类和类比较,除了不能实例化之外,没有任何区别;
abstract 关键字,不能和 static、private、final 等关键字搭配使用;
十一、接口
(一)、概述
接口,是 Java 语言中一种引用类型,是方法的集合;
( 二)、接口定义
接口的定义,与定义类的方式相似,但是使用 interface 关键字,也会被编译成 class 文件,但是要明确接口并不是类,而是另外一种引用数据类型;
接口就是一种约定、契约,一种规范;
1、含有抽象方法
使用 abstract 关键字修饰,可以省略,没有方法体,该方法供子类实现使用;
public interface InterfaceDemo {
public abstract void method();
}
2、含有默认方法和静态方法
默认方法:使用 default 修饰,不可省略,供子类调用 或 子类重写;
public default void fun(){
System.out.println("默认方法");
}
静态方法:使用 static 修饰,供接口直接使用;(用接口名调用)
public static void fun2(){
System.out.println("静态方法");
}
3、含有私有方法和私有静态方法
(三)、接口实现
接口要有实现类来实现接口中的抽象方法;
子类和抽象父类的关系是:extends
实现类和接口的关系是:implements
与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类;
非抽象子类实现接口:
1、必须重写接口中所有的抽象方法;
2、继承了接口的默认方法,即可以直接使用,也可以重写;
注意:
1、接口中抽象方法必须全部实现;
2、接口中默认方法可以继承,可以重写,二选一,但是只能通过实现类的对象来调用;
3、接口中静态方法只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用;
一个类可以实现多个接口
interface fun1{
void fun1();
}
interface fun2{
void fun2();
}
public class classInterface implements fun1,fun2 {
@Override
public void fun1() {
}
@Override
public void fun2() {
}
}
一个类继承同时可以实现接口
interface fun1{
void fun1();
}
interface fun2{
void fun2();
}
class superClass{
}
public class classInterface extends superClass implements fun1,fun2 {
@Override
public void fun1() {
}
@Override
public void fun2() {
}
}
接口多继承
interface fun1{
void fun1();
}
interface fun2{
void fun2();
}
interface childRen extends fun1,fun2{
void childRen();
}
class superClass{
}
public class classInterface extends superClass implements childRen {
@Override
public void fun1() {
}
@Override
public void fun2() {
}
@Override
public void childRen() {
}
}
(四)、和抽象类的区别
1、相同点:
①、都存在抽象方法;
②、不能创建对象,不能实例化;
③、可以作为引用类型;
④、具备 Object 类中所定义的方法;
2、不同点:
①、所有属性都是公开静态常量,隐式使用 public static final 修饰;
②、所有方法都是公开抽象方法,隐式使用 public abstract 修饰;
③、没有构造方法、动态代码块、静态代码块;
(五)、接口的好处
1、接口的出现降低了耦合性;
2、设计与实现完全分离,更容易更换具体实现;
3、更容易搭建程序框架;