1.面向对象思想
2.类的定义
3.对象的创建
4.构造方法
5.成员变量和局部变量
6.this关键字
7.封装
8.继承
9.重写
10.super关键字
11.static关键字
12.包机制
13.访问修饰符权限
14.多态
15.向上向下转型
16.抽象类
17.接口
18.代码块
19.值传递与引用传递
20.内部类
一、面向对象思想
1. 概述
是一种以事物为中心的编程思想。
2. 特征
封装:把描述一个对象的属性和行为封装成一个类,把具体的业务逻辑功能实现封装成一个方法,其次封装的意义还有效的保护属性通过访问修饰符私有化属性(成员变量),公有化方法。
继承:实现代码的复用,所有的子类所共有的行为和属性抽取为一个父类,所有的子类继承该类可具备父类的属性和行为,继承具有单一性和传递性。
多态:程序中定义的引用类型变量所指向的具体类型和调用的具体方法在程序编译阶段无法确定,而是在运行期间才能确定该引用类型变量指向具体哪个方向而调用在哪个类中声明的方法。
3. 面向对象和面向过程的对比
相同点:都是编程思想。
不同点:
面象过程是面向对象的基础,面向对象是基于面向过程的。
“面向过程”强调的是功能行为,面向过程”是一种以过程为中心的编程思想。“面向过程”他们不支持丰富的“面向对象”特性(比如继承、多态),就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向过程在这一系列工作的执行中,强调的是工作的执行。
举例:吃饭
面向过程
1:自己动手做
2:买菜
3:洗菜
4:煮饭炒菜
5:很难吃,浪费时间
面向对象
1:找专业对象(餐馆)
2:餐馆.点餐
3:餐馆.做饭
4:饭好吃,节约时间,精力
二、类的定义
1. 概述
类:是对对象所应当具有的特征的描述。类是抽象的存在。
2. 类的定义和使用
(1)使用已有的类
Java API提供了一些现成的类供我们使用,我们可以使用这些现有类来创建实例(对 象),比如:String、Object、包装类Integer、Long…集合类等等。
格式:类名 对象引用变量名 = new 类名 ();
例如:String s1 = new String(“Hello,World”); Object o = new Object();
(2)自定义类
除了使用现有API提供的类库,我们也可以自定义类。之前我们说过类是具有相同属性和相同操作的对象集合,属性就是成员变量,操作就是方法。所以,类的定义主要有两方面组成:成员变量(属性)和方法(行为)。
格式:
class 类名{
成员变量(属性)定义;
方法定义;
}
约定俗称的命名规则:
类名的首字母大写
变量名和方法名的首字母小写
采用驼峰命名标识
(3)属性
类的定义主要由属性和方法组成。属性是指类(这类事物)拥有的特征。属性,通常是名词。
例如:定义一个学生类,拥有的属性有:学号,姓名,年龄,家庭住址...
格式:[访问控制符] 数据类型 属性名 [=值]
示例
class Student{
int num; //学号
String name; //姓名
int age; // 年龄
String address; //家庭住址
...
}
(4)方法
类的另一个成员,方法(动词)。方法,指一个类的行为(动词)。
方法的四个要素:
1、访问控制符(修饰符)
2、返回值类型——(方法调用结束之后,返回给调用者的信息) void(方法没有返回值)
3、方法名——调用的时候用来区分
4、参数列表——参数--方法运行时,需要的额外的信息.方法有返回值,在方法中就一定要有return
示例
public void study(){
System.out.println(“努力学习”);
}
三、对象的创建
1. 概述
对象:代表现实世界中可以明确标识的一个实体。例如:一个学生、一张桌子、一间教室,一台电脑都可以看做是一个对象。每个对象都有自己独特的状态标识和行为。对象时具体的存在。
对象的属性(attribute,或者状态(state)):学生有姓名和学号,该学生特有的姓名和学号就是该学生(对象)的属性。
对象的行为(behavior),是由方法定义,调用对象的一个方法,其实就是给对象发消息,要求对象完成一个动作。可以定义学生对象 具备学习的行为。学生对象可以调用学习的方法,执行学习的动作。
2. 类和对象的关系
类是抽象的,对象是具体的。
类好比是图纸,对象好比是房子。类存在的理由:通过这个图纸,创建多个房子。
3. 创建对象
类创建对象的过程叫做实例化。java中实例化对象和数组相同,也是使用new关键字。
格式:类名 对象名 = new 类名();
例如:Student stu = new Student(); 创建一个Student类的对象实例(可以简称为创建一个Student类的对象),对象的名字叫做stu。
4. 创建对象的步骤
- 将要创建对象所属的类型字节码加载到方法区。
- 在栈内存中创建一个类型的引用,将来用于存储堆内存中对象的地址。
- 在堆内存中开辟空间,给各个成员变量分配内存空间
- 给成员变量进行赋值或者默认值。
- 将对象的地址,赋值给栈内存的引用。
5. 创建对象内存的说明
- 第一次使用某个类型的时候,会将该类型的字节码加载方法区,第二次使用的时候,不需要重复加载,在内存中只存在一份。
- 哪个对象调用方法,方法进入到栈内存中执行。
- 每次使用new关键字,都会在堆内存中开辟一块新的空间。
6. 对象成员的调用
访问属性:对象名.属性名
访问方法:对象名.方法名();
示例代码
class Test
{
public static void main(String[] args)
{
Car c1 = new Car();
c1.brand = "BMW";
c1.color = "green";
c1.num = 4;
c1.run();
c1.stop();
Car c2 = new Car();
c2.brand = "雅马哈";
c2.color = "red";
c2.num = 3;
c2.run();
c2.stop();
}
}
class Car
{
//属性--变量
String color;
String brand;
int num;
//行为--方法
public void run(){
System.out.println(color+"的"+brand+"车"+"靠着"+num+"个轱辘正在疯狂地奔跑");
}
public void stop(){
System.out.println(color+"的"+brand+"车"+"靠着"+num+"个轱辘正在努力地刹车");
}
}
内存分配图
7. 匿名对象
没有名字的实体,也就是该实体没有对应的变量名引用。
格式:new 类名()
匿名对象的用途
1、当对象对方法进行一次调用的时候,可以使用匿名对象对代码进行简化。
2、可以作为实际参数进行传递。
3、可以作为方法的返回值进行返回。
示例:new Car().num=5; new Car().clor="blue";
两个new 是两个不同的对象,在堆内存中有不同的空间,相互不相互干扰。
匿名对象的好处和注意事项
节省内存,容易进行被GC回收,匿名对象可以对属性进行赋值,但是毫无意义,但凡是对象名能使用的应用场景,匿名对象也可以。
四、构造方法
1. 概念
又称为构造器,C++称为构造函数,Java中称为构造方法或构造器。构造方法是一个对象刚刚出生时,调用的第一个方法。它一般从事一些初始化的工作。
2. 特征
1. 名字必与类名相同。
2. 参数可有可无,可多可少。
3. 没有返回值,所以void不写,更不用写return语句,如果非要加一个return,加上return;。
4. new 的时候被自动调用。
格式:
修饰符 方法名称(参数列表){
方法体;
}
代码示例
class Test
{
public static void main(String[] args)
{
Person p1 = new Person("jack");
System.out.println(p1.name);//jack
Person p2 = new Person("rose",20);
System.out.println(p2.age);//20
}
}
class Person
{
String name;
int age;
//无参构造方法
public Person(){}
//有参构造方法
public Person(String name){
this.name = name;
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
}
注意事项
1. 构造方法不需要手动调用,由JVM虚拟机在创建对象的时候自动调用。
2. 对象本身不能调用构造方法。
3. 构造方法只调用一次。
4. 如果没有构造方法,会默认生成一个无参无实现的构造方法。
5. 如果在类中任意写一个构造方法,默认的无参无实现的构造方法就不再生成。
6. 构造方法也可以发生重载。重载:同一个类,方法名称相同,参数类型或者个数不同,与返回值无关。
7. 一般在类中,既需要无参构造,也需要有参构造句,都需要手动定义。
3. 构造方法和set的比较
两种方式都可以给成员变量进行初始化赋值。
构造方法在创建对象的时候只初始化一次,后期需要改动的时候可以使用set方法。set方法比较灵活,可以多次调用。
4. 构造方法细节
1. 当类中没有定义构造方法时,系统会指定给该类加上一个空参数的构造方法。这个是类中默认的构造方法。当类中如果自定义了构造方法,这时默认的构造方法就没有了。
2.在一个类中可以定义多个构造方法,以进行不同的初始化。多个构造方法存在于类中,是以重载的形式体现的。因为构造方法的名称都相同。
五、成员变量和局部变量
1. 概念
成员变量:定义在类中的变量。
局部变量:定义在方法中定义的变量和方法的参数。
2. 区别
1. 定义的位置不同:成员变量:定义在类中方法外的成员位置的变量,局部变量:定义在方法内的变量和方法参数中定义的变量,就是局部变量。
2. 内存所存的空间不同:局部变量:属于方法,和方法的位置相同,方法存在栈内存中,所以局部变量也存在栈内存中。成员变量:属于对象,对象存储在堆内存中,所以成员变量也存储在堆内存中。
3. 生命周期不同:局部变量:属于方法,随着方法的调用而存在,随着方法的结束而消失。成员变量:属于对象,随着对象的创建而存在,随着对象的消失而消失(栈内存没有任何引用指向该对象,该对象就变成垃圾对象,随时被GC进行回收)。
4. 初始化状态不同:局部变量必须要进行初始化,否则不能使用;成员变量如果没有进行初始化,会有默认值,默认值如下图所示:
六、this关键字
1. 问题引入
我们发现 setXxx 方法中的形参名字并不符合见名知意的规定,那么如果修改成与成员变量名一致,是否就见名知意了呢?代码如下:
public class Student {
private String name;
private int age;
public void setName(String name) {
name = name;
}
public void setAge(int age) {
age = age;
}
}
经过修改和测试,我们发现新的问题,成员变量赋值失败了。也就是说,在修改了setXxx() 的形参变量名后,方法并没有给成员变量赋值!这是由于形参变量名与成员变量名重名,导致成员变量名被隐藏,方法中的变量名,无法访问到成员变量,从而赋值失败。所以,我们只能使用this关键字,来解决这个重名问题。
2. this的含义
this代表当前对象,就是所在方法所属对象的引用。简单说: 哪个对象调用了this所在的方法,this就代表哪个对象。
3. this调用成员变量
格式:this.成员变量名;
示例代码
public class User {
private int id;
private String name;
private int age;
public void setId(int id){ // 成员变量和方法参数同名
this.id = id;
//this.id 成员变量 id 方法参数
}
public int getId(){
return this.id;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
4. 调用构造方法
格式:this() 或 this(参数)
注意:调用时,必须放在构造方法的第一句(非注释内容)
代码示例
public User(int id,String name,int age){ //构造方法重载
this(); //必须放在第一行
System.out.println("User类的三个参数的构造方法");
this.id = id;
this.name = name;
this.age = age;
}
5. 变量的访问原则
变量访问的就近原则:当访问某个变量名称的时候,会先寻找最近的该变量名称的定义,如果找到了,就选用该变量,如果没有找到,才会找更远的位置寻找该变量。如果一直没找到,会编译报错。
当成员变量和局部变量重名时,先访问局部变量,如果该局部变量不存,再去寻成员变量。
示例代码
class Test
{
public static void main(String[] args)
{
Person p = new Person();
p.method(20);//20...10
Person p1 = new Person();