Java基础(六)★方法★面向对象★重载★重写

方法/函数

为了实现某段代码的重复利用

格式

修饰符 返回值类型 方法名(参数列表){

方法体;

return 返回值;

}

// 明确返回值类型---方法执行完成之后,返回值的数据类型是什么方法的返回值类型就是对应的类型---求整型数组的元素之和---确定返回值类型是int---如果方法执行完成之后没有返回值,那么返回值类型就是void
// 明确是否需要参数---如果方法执行过程中需要一些未知量参与运算,而未知量子啊方法中不能自动产生,那么这个时候需要以参数的形式体现---需要一个int类型的数组参与运算 
// 声明一个参数实际上就是声明了变量---形式参数---形参
// 方法签名---add(int[])
public static int add(int[] arr){
	int sum = 0;
	for(int i : arr){
		sum += i;
	}
	return sum;
} 
// 在调用函数传入的实际值---实际参数---实参
add(arr);

注意:

1.如果函数没有返回值,那么返回值类型定义为void

2. return之后的代码就执行不到了---一个函数一旦return,那么后续代码就不再执行了

3. 任何一个实体方法内都可以写return

练习:

1. 判断质数

2. 1000以内的亲密数--- A的所有因子(包含了1而不包含本身)之和等于B,并且B的所有因子(包含1而不包含本身)之和等于A,那么AB就是一对亲密数

3. 任何一个大于等于6的偶数都可以分解为两个质数之和。

6= 3 + 3;

14 = 3 + 11 = 7 + 7

18 = 5 + 13 = 7 + 11

方法的重载

当同一个类内出现了方法名一致而参数列表不同的方法的时候,构成了方法的重载。---方法名一致而参数列表不同---方法名+参数列表---方法签名

方法在调用的时候会进行最优匹配---找参数类型最符合的进行匹配。---如果进行方法的重载,尽量重载所有的情况,以防出现调用混乱的情况

方法的递归

函数调用自己本身就形成了递归。

public static int sum(int number){
	if(number <= 0){
		return 0;
	}
	return number + sum(number - 1);
}

练习:用递归求阶乘

n! = n* (n - 1)(n-2)...1  5 = 5 * 4 * 3 * 2 * 1 = 120

StackOverflowError---栈溢出错误---反应函数在栈中执行---函数在执行完成之前不会释放栈内存---递归的次数太多,就会出现这个错误

 


注意:在传递参数的时候,对于基本类型而言,传递的实际值;对于引用类型而言,传递的是地址。---只要地址不发生改变,函数中一切变化会作用于原数组

开发软件:Eclipse---日食

IDE---智能开发工具

Luna---Mars---Neon

绿色的,基于插件的,免费的,开源的

IDEA--Intelli J

MyEclipse

Alt+/ 快速提示键


面向对象

面向对象是相对面向过程而言的。面向过程注重的是过程,强调的是动作;面向对象注重的是对象,只要找到了对应的对象,那么就自然拥有了对象所具有的一切功能

面向对象是基于面向过程的。

面向对象一定优于面向过程吗?当场景比较复杂的时候,建议使用面向对象;当事物比较简单的时候,建议使用面向过程


类和对象的关系

根据一类事物进行抽取,将这一类事物用一个类表示,同时将这一类事物的共有特征抽取成属性,将这一类事物的共有行为抽取成了方法---将这些属性和方法放到了一个类中,用这个类表示这一类的事物---类是对象的抽取
/概括

根据类利用new关键字去创建该类对象的对象(实例),并且可以为对象的对应属性赋值,也可以去调用对应的方法---对象是类的实例化/具体化

对象在内存中的存储



对象在传值的时候传递的是地址

成员变量和局部变量之间有什么不同?

1. 定义位置:成员变量是定义在类内方法外;局部变量是定义在方法或者语句内部

2. 作用域:成员变量作用在整个类中;局部变量只能在定义的方法或者语句内部使用

3.内存存储位置不同:成员变量是随着对象的创建存储到了堆内存中,并且在堆内存中自动的赋予默认值;局部变量在方法或者语句执行的时候存储到了栈内存在中,不会自动给值

4. 生命周期不同:成员变量是随着对象的创建而加载到堆内存中,随着对象的回收而释放;局部变量在方法或者语句执行的时候才会创建,随着方法或者语句的结束而立即移除出栈内存

构造方法/函数

在类中与类同名而没有返回值类型的方法---主要是用于创建对象,在创建对象的时候实际上是在调用对应形式的构造函数

构造方法可以重载

如果一个类没有手动提供构造函数,那么JVM在编译的时候会自动添加一个无参的构造方法。

---构造函数可以重载

构造方法没有返回值类型,也没有返回值,能写return语句吗?---可以---规避风险

this关键字

注意:在Java中所有的非静态属性和非静态方法都是通过对象来调用的。

this代表当前在使用的对象---由于在类内没有实际对象的存在,所以通过this作为一个虚拟对象来调用本类中的其他方法和属性

可以通过this语句来调用本类中的其他对应形式的构造方法,--this必须放在构造函数的第一行

构造代码块

也叫初始化代码块。在构造函数执行之前先执行一次

在类内方法外用{}定义的代码块------在创建对象的时候先于构造函数执行---无论调用哪个构造函数都可以去执行某些必要的代码

局部代码块

在方法内或者语句内用{}定义的代码块---局部代码块---限制变量的生命周期从而提高内存的利用率

int i = 0;
while(i < 10);
{
System.out.println(i);
i++;
}

匿名对象

在代码中声明的没有名字的对象---在创建之后只能使用一次---可以作为参数进行传递

面向对象的特征

封装 继承 多态(抽象)

封装

封装的体现形式:

函数,属性的私有化---为了防止在类外直接操作属性的时候给属性赋值一些不符合常量的值,因此将属性私有化,提供了对外的访问方法来间接的操作属性---属性私有化保护了数据的安全性

优势:提高了代码的复用性,提高了代码的安全性

权限修饰符

用于限定变量或者方法的使用范围的

 

本类

子类

同包类

其他类

public

可以

可以

可以

可以

protected

可以

可以

可以

不可以

默认

可以

同包子类可以

可以

不可以

private

可以

不可以

不可以

不可以

public的使用范围最大

继承

如果一些类中有一些共有的方法和属性,将这些方法和属性提取出来放到一个新的类中,然后利用extends关键字让原来的类和新的类产生联系--这个关系称之为继承。新的类称之为父类(超类,基类),原来的类称之为子类(派生类)

Java中支持的是单继承---一个子类只能有一个父类,而一个父类可以有多个子类

子类通过继承父类可以使用父类中的一些方法和属性

Java中支持多层继承

单继承和多继承的优劣性比较:

多继承在代码的复用性上要优于单继承

优点:提高了代码的复用性,可以避免方法调用的混乱--使方法的调用更加安全

class A{
public int m(){
return 5;
}
}
class B {
public int m(){
return 10;
}
}
public class C extends A, B{} // C子类中可以从A,B父类中继承过来m方法
C c = new C();
int i = c.m(); // 多继承会导致方法调用的混乱

方法的重写

当父子类中产生了方法签名完全一致的方法的时候,构成了方法的重写/覆盖

注意:方法的重写遵循 两等两小一大 这五个要求

1. 方法签名要求完全一致

2. 如果父类中方法的返回值类型是基本类型/void/最终类,子类中重写的方法的返回值类型必须一致

class A {
public void m(){}
}
class B extends A {
public void m(){}
}

3.如果父类方法的返回值类型是引用数据类型,那么子类重写的方法的返回值类型是父类方法返回值类型的子类或者是本身

class A {}
class B extends A{}
class C{
public A m(){
return null;
}
}
class D extends C {
public B m(){
return null;
}
}

4. 子类方法的权限修饰符的范围要大于等于父类方法的权限修饰符的范围

class A{
protected void m(){}
}
class B extends A{
public void m(){}
}

注意:八种基本类型之间没有继承关系的

super关键字

super表示在子类中代表了父类的对象---通过super来调用父类中的方法或者属性---可以将super看成一个虚拟对象

super语句---在子类构造函数中通过调用super语句来创建一个父类对象---如果父类中没有提供无参构造,那么这个时候子类的构造函数中手动添加一个super语句---super语句必须放在子类构造函数的首行

子类的构造函数中必然直接或者简介的有一个super语句---在创建子类对象的时候必然先创建一个父类对象

多态

编译时多态:函数的重载

运行时多态:函数的重写 向上造型---基于继承,继承是运行时多态的前提

行为多态:函数的重载和重写

对象多态:向上造型


Animal a  = new Lion();---在编译时期并不会真正的关心是哪个具体的子类,在运行的时候需要确定是哪个具体的子类以分配空间

注意:向上造型用父类声明用子类初始化---由于这个对象是父类声明的,所以对象能够干什么需要看父类;由于是用子类初始化,具体怎么干要看子类

重写的理解

1. 子类中重写的方法的权限修饰符要大于等于父类

class A {
public void m(){}
}
class B extends A {
void m(){}
}
A a = new B(); // 声明a对象的时候用的A类,那么A类告诉a对象可以使用一个m方法,并且告诉a对象这个m方法是一个public修饰的方法在任何地方都可使用
a.m(); // 具体的实现用的是B这个子类,当执行方法的时候需要看具体子类,发现这个方法使用默认权限修饰的

2. 如果父类方法的返回值类型是引用类型,那么子类重写的方法的返回值类型是父类方法返回值类型本身或者子类

class A {
public void ma(){}
}
class B extends A {
public void mb(){}
}
class C {
public B m(){/*more code here*/}
}
class D extends C {
public A m(){/*more code here*/}
}
C c = new D(); // 声明c对象用的是C类,C类告诉c对象有一个m方法可以使用,并且这个m的方法的返回值类型是一个B类型
B b = c.m(); // 方法的具体执行要看子类,子类中实际上这个方法的返回值类型是A---子类对象接了一个父类对象
b.mb(); // 子类接了一个父类对象,所以实际上是一个父类对象,而父类对象中不一定含有子类中独有的方法

3. 如果父类方法的返回值类型是基本类型/void/最终类的时候,子类的方法的返回值类型要一致----基本类型之间没有继承关系

能够用子类来接住一个父类对象么?---不行

B -> A

B b = new A(); 

static

修饰变量、方法、代码块、内部类


静态变量

static修饰变量---静态变量,也叫类变量---随着类的加载而加载到了方法区中的静态区,并且在静态区中自动赋予了一个默认值。静态变量先于对象而存在,所以静态变量可以不通过对象而通过类来调用,也可以通过对象来调用。该类产生的所有的对象实际上存的是该静态变量在静态区中的地址,静态变量是被所有对象所共享的。

静态变量是先于对象而存在,所以静态变量可以不通过对象而通过类名来调用

System.out  System.in

 

静态变量可以定义在构造代码块中吗?---不可以

静态变量可以在构造代码块中初始化吗?---可以

方法区

存储类信息。存储类的基本信息的区域称之为静态常量池。存储静态属性和静态方法的地方称之为静态区。

一个类在第一次真正使用的时候才会向方法区中加载---所以类只加载一次,加载完成之后就不再从方法区中移除。

静态方法

static修饰方法---静态方法,也叫类方法---在类加载的时候加载到了方法区中静态区,只是存储在静态区,并不执行,而是在方法被调用的时候到栈内存中执行。静态方法先于对象而存在的,所以静态方法可以通过类名来调用,也可以通过对象来调用。

System.arraycopy()

Arrays.toString()

Arrays.copyOf()

Math.sqrt()

System.out.println();---out是一个静态对象

 

静态变量可以定义到静态方法中吗?---不可以---静态方法在静态区中只存储不执行

静态方法中可以直接调用本类中的非静态方法吗?---不可以

能在主函数中使用this或者super吗?---不可以

静态方法可以重载吗?---可以

Arrays.sort()

静态方法可以重写(覆盖)吗?---不可以

父子类中可以存在方法签名完全一致的静态方法吗?---可以

静态看的是声明类,非静态看的是实现类---可以---如果父子类中存在了方法签名完全一致的方法,要么都是静态的,要么都是非静态的。

静态代码块

static{}包括起来的代码

在这个类第一次被真正使用(第一次创建对象/调用方法)的时候执行一次。

执行顺序:

先父后子,先静后动-------父类静态->子类静态->父类非静态->子类非静态

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值