面向对象
一、面向对象与面向过程
1.面向过程
a.简介
- 面向过程它重点强调的“功能行为”,它的核心主体函数,考虑的是做
什么,是如何有序将功能执行完成。
2.面向对象
a.简介
- 面向对象它重点强调的”功能的对象”,也就是说将功能行为封装到对
象里面,它的核心主体是类/对象,它考虑的是 谁 将功能实现
3.举例
- 面向过程的写法
吃(猪八戒,西瓜)
- 面向对象的写法
猪八戒.吃(西瓜)
4、类与对象之间的关系
- ①先有类,才有对象。② 类只有一个,对象可以多个。 ③ 对象依赖于类。
二、如何定义一个类
- 使用的语法: 类中只能用public或者缺省修饰 。类也可以用 final、abstract类型修饰
修饰符 class 类名
{
//主体
1、成员变量(属性)
2、行为方法
3、构造器
4、初始化块
5、内部类
}
三、对象的创建(也叫实例化)
-
①通过 new 关键字+构造器名(实参) ② **通过反射机制 **
-
举例
/* 定义Car类 */ class Car{ //添加构造器 public Car(String brand){ //这个是空的构造器 //这个里面定义属性 //当想要有一个return返回时(Car前面需要有对应的基本数据类型) } public Car(){ //定义属性 } } public class MainTest{ public static void main(String[]args){ //如何创建此类对象 Car c=new Car(); } }
-
成员变量(属性)也叫全局变量
class Person { //成员变量(属性) 修饰符 数据类型 成员变量名=默认值 }
-
修饰符
- static方法:
- 当被static 修饰的变量时、它的变量就变成类变量、且这个依赖类存在
- static方法:
-
final:
-
此方法不可被子类所重写
注意:final与static之间可以并存- abstract:
- 抽象方法(此方法没有方法体)
- 数据类型:
- 基本数据类型 或者 引用类型
- 什么是引用?其实就是所在的**“指针”** ,也是指向内存空间的地址
- abstract:
-
2、成员变量的调用
-
重点:成员变量它是依赖于对象,所以操作成员变量,首先要创建对象,
有对象,才能操作属性(注)当是static修饰的时候就不是依赖对象,而是依赖类 -
操作:引用变量名.成员变量名
-
举例
-
/* 定义Car类 */ class Car { //品牌(成员变量) public String brand; public double price; } public class MainTest { public static void main(String[] args) { //如何创建此类对象 Car c = new Car(); c.brand = "宝马"; c.price = 300000.00; System.out.println("车的品牌=" + c.brand + " 车的价格 = "+c.price); + 7System.out.println("7" + 7 + "7" + 7 + 7);//77777(重点:!!后面的7+7为什么不等于14,而是 77,因为,前面是string类型,然后全部变成字符串格式了) System.out.println(7 + 7 + "7" + 7 + "7");//14777(重点:!!!这个由于是前面是数值类型,且连接的都是同样类型) } }
五、jvm的内存原理
1、jvm的简介
- 当类加载到内存,它就会产生内存区域(运行时的数据区)
- 内存区域产生的时机
- jvm的运行过程
2.内存区域图
3.重点分析内存区域
-
方法区
- 静态元素(static修饰)
- 编译后的代码段
- 常量池
- 字符串常量池(从jdk1.8,字符串常量池从方法区移动到堆区存
储) - 整型常量池
- 字符串常量池(从jdk1.8,字符串常量池从方法区移动到堆区存
-
虚拟机栈
- 方法的局部变量
- 方法的返回值
- 方法的参数
-
堆区
- 对象
- 数组数据
- 字符串常量池(jdk1.8从方法区转到堆区)
- 全局变量
2、1实例
java Test
class Person{
public static String name=”gec”;
public int age
}
public class Test{
public static void main(String[]args){
Person p=new Person();
p.age=30;
}
}
。jvm的案列解析
2.2 数组实例
public class MainTest {
public static void changeArraysValue(int[] a) {
//修改数组里面的数据值,每个元素值加10
int[] b = {10, 20, 30};
a = b;
}
public static void main(String[] args) {
int[] a = {1, 2, 3};
changeArraysValue(a);
for (int v : a) {
System.out.println("v=" + v);
}
}
}
- 内存图
六、行为方法
1、什么是行为方法
- 对象的功能行为,也就是对象的封装行为动作
- 举例
- 针对Car 对象,有吃和睡等操作行为
2、行为方法的定义
class 类{
//属性
//行为方法
修饰符 返回值的数据类型 方法名(形参....) 修饰符:private、public、protected、default {
//方法主体
}
}
-
修饰符
-
static方法
- (从行为方法变成类方法)
- 此方法不依赖于对象而存在,依赖于类,也就是此方法
的调用只需要类名即可
-
final
- 此方法不可被子类所重写
注意final与static之间可以并存
- 此方法不可被子类所重写
-
abstract
- 抽象方法(此方法没有方法体)
-
返回值的数据类型
- 基本数据类型 或者 引用类型(类、数组、)
-
3、调用行为方法
-
引用变量名.方法名(实参值)
-
举例
class Cat{ /* 定义一个行为方法 4、不确定的参数个数 语法 */ public void eat(String name,String thing){ System.out.println("cat name="+name+" eat"+thing); } } public class MainTest{ public static void main(String[]args){ //创建Cat的对象 Cat c=new Cat(); c.eat("大罗","fish"); } }
- 对上面代码的图形解释
4、不确定参数
-
当形参中使用(String … thing)这个是数组形式
//thing其实就是一个数组类型 class Cat{ /* 定义一个行为方法 */ public void eat(String ... thing){ //通过foreach的写法: for(String v:thing){ System.out.println("cat eat"+v); } System.out.println("----------------"); } public class MainTest{ public static void main(String[]args){ //创建Cat的对象 Cat c=new Cat(); c.eat("fish"); c.eat("fish","meal"); c.eat("fish","meal","xxx"); c.eat("fish","meal","xxx","ttt"); } }
七、方法重载
1、什么是方法重载
-
方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数(注意!!!!重载的是强调方法相同,形参不同,方法前的有返回无返回是没影响的)
-
注意,不能根据方法的返回类型进行判断是否是重载
如下案例(错误的方法重载)
正确的方法重载
2.方法的参数值传递
- a、针对基本数据类型传递
- 举例代码如下
- 输出的结果:为什么在输出的结果中,数值是没有变的!!!!!
- 根据jvm内存图进行描述
-
b.针对引用数据类型传递
-
举例代码
class SwapCls { public int a; public int b; } public class MainTest { public void swap(SwapCls t) { int temp = t.a; t.a = t.b; t.b = temp; } public static void main(String[] args) { SwapCls c = new SwapCls(); c.a = 4; c.b = 5; System.out.println("交换之前的 a=" + c.a + " b = "+c.b);// 4,5 //匿名方式创建对象 new MainTest().swap(c); System.out.println("swap方法调用之后"); 内存图 System.out.println("交换之后的 a=" + c.a + " b = "+c.b); } }
-
输出的结果
-
交换之前是 a= 4 ; b= 5
-
交换之后是 a = 5 ; b =4
-
内存图
八、static 和 this 用法
1、static概述
-
静态修饰
-
什么静态?
- 所有被static修饰的成员,都是依赖于类而存在,与对象没有任何关系
-
static能修饰那些元素
-
static修饰成员变量
-
此成员变量变成类变量
class Test { public static int a; }
-
-
static修饰行为方法
-
此方法变成类方法
class Test { public static void main(String[]args) { ..... } }
-
-
static修饰内部类
-
静态内部类
class Outer { static class Inner { ... } }
-
-
static修饰初始化块
class Test { //静态初始化块 static { .... } }
-
2、如何调用类元素
-
如果调用类变量
类名.变量名
-
如果调用类方法
类名.类方法名(参数值.....)
3、static的特点
-
static修饰元素依赖于类而存在,与对象没有关系
- 举例
class Apple { public static float weight; } public class MainTest { public static void main(String[]args) { Apple t1=new Apple(); t1.weight=1.3f; Apple t2=new Apple(); t2.weight=1.4f; Apple t3=new Apple(); t3.weight=1.5f; Apple.weight=1.6f; System.out.println("第一个苹果对象重量="+t1.weight); System.out.println("第二个苹果对象重量="+t2.weight); System.out.println("第三个苹果对象重量="+t3.weight); } }
- 上述代码体现内存图
-
静态方法是否能直接调用非静态元素?
class Apple { public float weight; //定义一个静态方法 public static void printWeight() { //静态方法不能直接访问(成员变量和行为方法) System.out.println("print weight="+weight); } }
-
行为方法是否能直接访问静态元素?
-
行为方法是可以直接访问静态元素,原因:行为方法依赖于对象,对象依赖于类,因此行为方法肯定可以访问静态元素
class Apple { public static float weight; //定义一个行为方法 public void printWeight() { //行为方法直接访问静态变量 //System.out.println("print weight="+weight); System.out.println("print weight="+weight); } }
-
-
静态方法是否能直接访问静态元素?
-
肯定可以
-
原因:都是依赖于类而存在
class Apple { public static float weight; //定义一个类方法 public static void printWeight() { //类方法直接访问静态变量 //System.out.println("print weight="+weight); System.out.println("print weight="+weight); } }
-
4、this用法
-
①this其实就是一个引用变量,它指向本类自身对象
-
②作用范围、
- 在方法内部、在构造器里面、在初始化块、在内部类
-
③作用
- 通过this,可以访问成员变量、行为方法、调用构造器
-
④举例
class Cat { //成员变量 public int legs; public void info() { System.out.println("cat legs=" + legs); //this其实就是一个引用变量,它指引对象本身 System.out.println("cat legs=" + this.legs); } } public class MainTest { public static void main(String[] args) { Cat t = new Cat(); t.legs = 4; t.info(); } }
- 当方法的形参名与成员变量名冲突 ,必须要添加this引用变量!!!如下是没有添加this的,这个里面legs按就近原则指的是形参里面的参数,所以想调用的话就是使用this
正确调用
证明this其实就是自身对象的指引
class Cat {
//成员变量
public int legs;
public void setLegs(int legs) {
this.legs = legs;
}
public Cat getCatObj() {
//this指引的对象就是此方法所依赖的对象
return this;
}
public Cat getCatObj2() {
return new Cat();
}
public void info() {
System.out.println("cat legs=" + legs);
//this其实就是一个引用变量,它指引对象本身
System.out.println("cat legs=" + this.legs);
}
}
public class MainTest {
public static void main(String[] args) {
Cat t = new Cat();
//t.legs=4;
t.setLegs(4);
t.info();
Cat t2 = t.getCatObj2();
t2.legs = 8;
t.info(); //8
}
}
九、局部变量
1、概述
- 此变量是在一定的范围区域里有效,在范围区域外此变量是不可用的
- 范围区域
- 方法体
- 初始化快
- 构造器
2、成员变量和局部变量的区别
- 成员变量可以类的任何位置访问
- 局部变量只能在局部范围访问
- 成员变量分配在堆区
- 局部变量栈区
- 成员变量系统会默认初始化
- 局部变量必须要显示初始化数据指
十、构造器
1.构造器的定义
-
a.语法(可以用public、 private、 protected、default修饰)
-
b.不能使用(static、final、abstract修饰)
-
c.构造器名必须类名一致
-
d.构造器不是没有返回值,而是把值隐藏了
public class Animal{ //定义一个构造器 //修饰符 构造器名(形参....) 构造器名要跟类名相同 { 构造器的主体 } }
2.构造器的调用时机
- 当你实例化类、产生对象、会触发构造器
3.构造器的作用
- 使本类的对象能够被外部所访问
- 能够针对对象的成员变量进行初始化处理
4.构造器的特征
-
构造器主要是针对成员变量进行数据初始化
-
如果程序员没有往此类添加构造器,jvm会生成一个默认构造器
-
如何程序员主动添加构造器,则jvm不会添加 一个默认构造器
-
构造器支付重载
-
构造器与构造器之间相互调用
-
依赖于:this(对应的实参)
对this的调用必须是构造器中的第一个语句
-