(九)面向对象上

面向对象学习主线:
1、Java类与类的成员:属性、方法、构造器、代码块、内部类
2、三大特征:封装性、继承性、多态性
3、其他关键字:this、super、static、final、abstract、interface、package等

目录

一、类与对象概述

二、属性

三、方法

方法概述

2、方法的重载

3、可变个数形参方法

4、Java的值传递机制

5、递归方法

四、封装性

五、构造器

六、this关键字

七、package和import

1、package

2、import


一、类与对象概述

1、面向对象与面向过程的理解:

面向过程:以函数为最小单位,强调功能行为,考虑怎么做。

面向对象:强调具备功能的对象,以类/对象为最小单位,考虑谁来做。

例如:把水果装进冰箱

面向过程:①把冰箱门打开②把水果放入冰箱③关闭冰箱门(怎么做)

面向对象:人{属性、行为} 水果{属性、行为} 冰箱{属性、行为}

2、面向对象中的两个重要概念:

类:对一类事物的描述,是抽象的、概念上的定义。

对象:是实际存在的该类事物的每个个体,因而也称为实例(instance)。

二者的关系:对象是由类new出来的,是派生出来的。

面向对象程序设计的重点就是类的设计,设计类就是设计类的成员。

3、面向对象思想实现的规则一

  • 创建类,设计类的成员
  • 创建类的对象
  • 通过 “对象.属性” 或 “对象.方法” 调用对象的结构

 补充:以下几个概念等同:

  •         属性=成员变量=field=域、字段
  •         方法=成员方法=函数=method
  •         创建类的对象=类的实例化=实例化类

 4、对象的创建与对象的内存解析

创建:Person p1=new Person();Person p2=new Person();

Person p3=p1;//没有新创建对象,共用一个堆空间中的对象实体。

说明:如果创建了一个类的多个对象,则每个对象(非static的)都独立拥有一套类的属性,例如p1和p2,意味着如果修改对象p1的属性a,则不影响对象p2中的属性a的值。

内存解析:

 5、匿名对象

定义:创建对象时,没有显式的赋给一个变量名,即为匿名对象。

特点:匿名对象只能调用一次

例如:

new Phone().sendEmail();//蓝色即为匿名对象,后面是调用的方法

new Phone().playGame();

应用场景:

class PhoneMall{

        public void show(Phone phone){

                phone.sendEmail();

                phone.playGame();

        }

}

Phone mall=new PhoneMall();

mall.show(new Phone());//匿名对象的使用

6、JVM内存结构:

编译完源程序以后,生成一个或多个字节码文件。我们使用jvm中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,运行时需要将字节码文件对应的类加载到内存中,涉及到内存解析。

 将局部变量存储在栈空间中,即虚拟机栈中;将new出来的结构(比如:数组、对象)加载在堆空间中,对象的非static属性也加载在堆空间中;方法区:类的加载信息、常量池、静态域。

二、属性

对比:属性(成员变量)VS局部变量

1、相同点:

  • 定义变量的格式:数据类型 变量名=变量值
  • 先声明,后使用
  • 变量都有其对应的作用域

2、不同点:

  • 在类中声明的位置不同

        属性:直接定义在类的一对{ }内。

        局部变量:声明在方法内、方法形参处、代码块内、构造器形参、构造器内部的变量

  • 关于权限修饰符不同

        属性(成员变量):可以在声明属性时,指明其权限,使用权限修饰符。 常用的权限修饰符有:private、public、缺省、protected

        局部变量:不可以使用权限修饰符

  • 默认初始化值的情况 

        属性:类的属性、根据其类型、都默认初始化值:

                整型(byte、short、int、long:0)

                浮点型(float、double:0.0)

                字符型(char:0或'\u0000')

                布尔型:(boolean:false)

                引用数据类型(类、数组、接口:null)

        局部变量:没有默认初始化值,因此,在调用局部变量之前一定要显示赋值。

  • 在内存中加载的位置

        属性:加载到堆空间中(非static)

        局部变量:加载到栈空间

补充:变量按照在类中声明的位置分:

三、方法

方法概述

1、定义:描述类应该具有的功能

2、方法的声明:权限修饰符 返回值类型 方法名(形参列表)

说明:

①关于权限修饰符:Java规定的4种权限修饰符:private、public、缺省、protected

②返回值类型:如果方法有返回值,则必须在方法声明时,指定返回值类型,同时在方法中需要使用return关键字来返回指定类型的变量或常量;如果没有返回值,则方法上名师,使用void来表示。对于定义方法该不该设返回值,要具体问题具体分析。

③方法名:属于标识符,遵循标识符的规则和规范。

④形参列表:方法可以声明0个、1个或多个形参,格式为:数据类型  形参1,数据类型  形参2,......,定义方法时该不该定义形参,还需要具体问题具体分析。

⑤方法体:方法功能的体现。

3、方法的使用:方法中可以调用当前类的属性或方法,也可以自己调用自己(递归方法),在方法中不能再定义方法。

补充:关于return关键字:

①使用范围:使用在方法体中

②作用:结束方法;针对于返回值类型的方法,使用“return 数据”方法返回所要的数据。

③return关键字后面不可以声明执行语句。

方法的重载

1、定义:在同一个类中,允许存在一个以上的同名方法,只要它们的形参个数或者参数类型不同即可。

总结:“两同一不同”:同一个类、相同方法名;形参列表不同:参数个数不同或者参数类型不同。

2、举例

构成重载的举例:

public void getSum(int i,int j){
    System.out.println("method1");
}
public void getSum(double d1,double d2){
    System.out.println("method2");
}
public void getSum(String s,int i){
    System.out.println("method3");
}
public void getSum(int i,String s){
    System.out.println("method4");
}

不构成重载的举例:下面的方法不构成重载

public int getSum(int i,int j){

        return 0;

}

public void getSum(int m,int n){

}

private void getSum(int i,int j){

}

总结:判断是否构成方法的重载严格按照两同一不同,跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系。

3、如何确定类中某一个方法的调用:方法名——>参数列表

补充:对象类型数组:

//声明Student数组
Student[] stu=new Student[20];
for(int i=0;i<stu.length;i++){
    //给数组元素赋值,所赋的值为一个Student对象
    stu[i]=new Student();
    stu[i].number=(i+1);
    //随机生成一个1-6的年级数
    stu[i].state=(int)(Math.random()*(6-1+1)+1);
    //随机生成一个0-100的分数
    stu[i].score=(int)(Math.random()*(100-0+1));
}

可变个数形参方法(jdk 5.0新增)

1、使用说明:

  • 可变个数形参格式:数据类型  ... 变量名。
  • 当调用可变个数形参的方法时,传入的参数个数不定,可以是:0个,1个,2个······
  • 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载,与形参类型相同的数组形参之间不构成重载。
  • 可变个数形参在方法的声明中,必须声明在末尾。
  • 可变个数形参方法最多只能声明一个。

2、举例说明

public void show(int i){
	    System.out.println("method1");
	}
	public void show(String s) {
		System.out.println("method2");
	}
	public void show(String ... strs){
	    System.out.println("method3");
	    for(int i=0;i<strs.length;i++) {
	    	System.out.println(strs[i]);
	    }
	}
//下面的方法不能与可变个数形参方法同时存在,对应使用说明中的第三点
public void show(String[] strs){

}

3、调用

调用时可随意指定形参个数,也可以是数组形参:

test.show("hello");//一个形参

test.show("hello","world");//两个形参

test.show();//0个形参

test.show(new String[]{"AA","BB","CC"});//形参数组

4、Java的值传递机制

1、针对方法内变量的赋值举例:

基本数据类型:

int m=10;

int n=m;

System.out.println("m=" + m + ",n=" + n);//m=10,n=10

n=20;

System.out.println("m=" + m + ",n=" + n);//m=10,n=20

引用数据类型:

Test t1=new Test();
t1.id=1001;

Test t2=t1;
System.out.println("t1.id="+t1.id+",t2.id="+t2.id);//t1.id=1001,t2.id=1001
t2.id=1002;
System.out.println("t1.id="+t1.id+",t2.id="+t2.id);//t1.id=1002,t2.id=1002

说明:变量赋值规则:

  • 如果变量是基本数据类型,此时赋的值是变量所保存的数据值。例如例子中的int n=m,是将m保存的值赋值给n。
  • 如果变量是引用数据类型,此时赋的值是变量所保存的数据的地址值。例如Test t2=t1,是将t1保存的地址值赋值给了t2。

2、针对方法的参数概念:

        形参:定义方法时,声明的小括号内的参数。

        实参:方法调用时,实际传递给形参的数据。

3、Java中参数传递机制:值传递

规则:

  • 如果参数是基本数据类型 ,此时实参赋给形参的是实参真实存储的数据值。
  • 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。

递归方法

1、定义

递归方法:一个方法在方法体内调用它自身。

2、理解

  • 方法递归包含了一个隐式的循环,它会重复执行某段代码,但这种重复执行无需循环控制。
  • 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。

 3、举例:

计算1-n之间所有自然数的和

public int getSum(int n){

        if(n==1){

                return 1;

        }else{

                return n+getSum(n-1);

        }

}

四、封装性

1、封装性思想具体的代码体现:

体现1:将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值

private double radius;
public void setRadius(double radius){
    this.radius=radius;
}
public double getRadius(){
    return radius;
}

体现2:不对外暴露的私有的方法

体现3:单例模式(将构造器私有化)

体现4:如果不希望类在包外被调用,可以将类设置为缺省的。

2、Java规定的四种权限修饰符

2.1权限从小到大顺序为:

private < 缺省 < protected < public

2.2具体修饰范围:

 

4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类,修饰类的话,只能用缺省或public。

五、构造器(构造方法)

1、构造器的作用:

  • 创建对象
  • 初始化对象的信息

person p=new person()//创建对象:new+构造器

person p1=new person(“Tom”);//创建对象的同时初始化对象信息

public person(){

        age=18;//此时所有的对象年龄都是18,即初始化属性

}

2、使用说明:

  • 如果没显示地定义类的构造器的话,则系统默认提供一个空参的构造器
  • 定义构造器的格式:权限修饰符 类名(形参列表){}
  • 一个类中定义的多个构造器,彼此构成重载
  • 一旦我们显示的定义了类的构造器之后,系统就不再提供默认的空参构造器
  • 一个类中,至少会有一个构造器

3、举例

public Person(){

        System.out.println("Person().......");

}

public Person(String n){

        name=n;

}

public Person(String n,int a){

        name=n;

        age=a;

}

补充总结:

1、属性赋值的先后顺序

①默认初始化

②显式初始化

③构造器中初始化

④通过“对象.方法”或“对象.属性”的方式,赋值

以上操作的先后顺序:①——②——③——④

2、Javabean的概念

所谓JavaBean,是指符合如下标准的Java类:

  • 类是公共的
  • 一个无参的公共的构造器
  • 属性以及对应的get、set方法

六、this关键字

1、可以调用的结构:属性、方法、构造器

2、this调用属性、方法:

this理解为:当前对象或当前正在创建的对象

2.1在类的方法中,我们可以使用“this.属性”或“this.方法”的方式,调用当前对象属性或方法。但是,通常情况下,我们都选择省略"this.",特殊情况下,如果方法的形参和类的属性同名时,我们必须显示地使用“this.变量”的方式,表明此变量是属性,而非形参。

2.2在类的构造器中,可以使用“this.属性”和“this.方法”的方式,调用当前正在创建的属性或方法。但是,通常情况下,我们都选择省略“this.”,特殊情况下,如果构造器的形参和类的属性同名时,我们把必须显示的使用“this.变量”的方式,表明此变量是属性,而非形参。

3、this调用构造器:

在类的构造器中,可以显示的使用“this(形参列表)”方式,调用本类中指定的其他构造器,构造器中不能通过“this(形参列表)”方式调用自己。意味着如果一个类中有n个构造器,则最多有n-1个构造器中使用了“this(形参列表)”。

规定:“this(形参列表)”必须声明在当前构造器的首行;构造器内部,最多声明一个“this(形参列表)”,用来调用其他构造器。

package和import

package

1、使用说明:

  • 为了更好的实现项目中类的管理,提供包的概念
  • 使用package声明类或接口所属的包,声明在源文件的首行
  • 包,属于标识符,遵循标识符的命名规则、规范(均小写)

2、举例:MVC设计模式

模型层(model):主要处理数据

  • 数据对象封装 model.bean/domain
  • 数据库操作类:model.dao
  • 数据库 model.db

控制层(controller)处理业务逻辑

  • 应用界面相关 controller.activity
  • 存放fragment controller.fragment
  • 显示列表的适配器 controller.adapter
  • 服务相关的 controller.service
  • 抽取的基类 controller.base

视图层(view)显示数据

  • 相关工具类 view.utils
  • 自定义view view.ui

说明:每“ . ”一次,就代表一层文件目录

 3、JDK中的主要包介绍:

 

import(导入):

  • 在源文件中显示的使用import结构导入指定包下的类、接口
  • 声明在包的声明和类的声明之间
  • 如果需要导入多个结构,并列写出即可
  • 可以使用“ xxx.* ”的方式,表示可以导入xxx包下的所有结构
  • 如果使用的类或接口是java.lang包下定义的,则可以省略import结构
  • 如果使用的类或接口是本包下定义的,则可省略import结构
  • 如果在源文件中,使用了不同包下的同名的类,则必须至少一个类需要以全类名的方式显示

例如以下语句,Account类是不同包下同名的类,第一个类通过导入com.exer1包即可,第二个类就要以全类名的方式显示:

Account acct=new Account(1000);//Account类是在com.exer1包中

com.exer2.Account acct1=new com.exer2.Account(1000,2000,0.0123);//这个Account类是在  com.exer2包中 

  • 使用“ xxx.* ”方式表明可以调用xxx包下的所有结构,但不包括子包,如果使用的是xxx子包下的结构,仍需要显式导入。例如:com.exer2下在创建一个子包exer3,则此时exer3的显示路径为com.exer2.exer3,此时要调用exer3下的结构时,仍需要使用import com.exer2.exer3显式导入
  • import static:导入指定类或接口中的静态结构:属性或方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值