[上一篇](https://blog.csdn.net/CHiN_951/article/details/134791611?spm=1001.2014.3001.5502)
面向对象的程序设计(OOP:object oriented programming)
面向过程:C
面向对象:Java
程序是为了解决现实问题,模拟现实世界
在java码农的眼中,世界是由对象组成的
手机:长啥样,和能做什么
描述:品牌,logo,价格,颜色,内存,颜色… (外观描述)
功能:接打电话,收发短信,能聊微信… (功能描述)
车:长啥样,和能做什么
一切可以被描述的实体都是对象
行为:有什么动作,能做什么,指程序中的方法,一般使用动词.(方法)
特征:长什么样,指程序中的属性,一般使用名称.(变量)
程序中的对象是通过现实中的对象虚拟出来的
现实中有对象的"模板",在程序中也需要对象的"模板"
类是对象的"模板"
在一组相同或相似的对象中,抽取出共同的特征和行为,保留关注的部分
抽象的概念
类的由来,相同或相似的对象中,抽取出共同的特征和行为
如何定义一个类:
1.确定类名,首字母大写,数字字母下划线美元符组成,数字不能开头,驼峰命名法则…
2.编写类的成员
成员:变量(特征,属性),方法(行为)
// 1.类名确定
public class Phone {
// 2.编写成员
// 变量
String brand;//品牌
double price;//价格
String color;//颜色
// 方法
// 打电话的方法
public void call() {
System.out.println("我打电话....");
}
// 聊微信的方法
public void vx() {
System.out.println("我聊微信");
}
}
创建对象使用new关键字,类可以创建对象
语法
类名 对象名 = new 类名();
例如:Phone p1 = new Phone(); 对象名就是变量名
对象可以调用类模板中的成员
// 测试模板(创建对象)
public class Test01 {
// 程序的入口
public static void main(String[] args) {
// 创建对象
Phone p1 = new Phone();
// 对象可以调用模板(类)中的成员
// 为类的变量赋值
p1.brand = "苹果";
p1.price = 8900;
p1.color = "red";
// 使用变量的值
System.out.println(p1.brand);
System.out.println(p1.price);
System.out.println(p1.color);
// 调用方法
p1.call();
p1.vx();
// 创建对象
Phone p2 = new Phone();
p2.brand = "华为";
p2.price = 6888;
p2.color = "金色";
System.out.println("手机型号为:"+p2.brand);
p2.call();
p2.vx();
}
}
类:对象的模板,定义了(抽象了)对象具有的特征和行为
对象:类的具体化/实例化,拥有多个相同或相似特征和行为的实体(真实存在/使用程序虚拟出来的)
面向对象:从具体到抽象(从真实对象到创建程序类的过程),再从抽象到具体(通过类模板创建对象的过程)的过程
对象和类的先后顺序?
设计程序时:先有对象,再有类
实现编码时:先有类,再有对象
实例变量,就是属性,也可以称为成员变量(类似于c中的全局变量)
方法中的变量就是局部变量
区别 | 局部变量 | 实例变量 |
---|---|---|
位置 | 定义在方法内 | 定义在类中,方法之外 |
默认值 | 没有默认值,必须赋值才能使用 | 系统会为所有的实例变量提供默认值,和数组的默认值一样 |
作用域(使用的范围) | 所在方法内{} | 整个类中 |
名称 | 同一方法中局部变量不能同名 | 同一个类中实例变量不可以重名 |
生命周期 | 方法执行完之后就会被销毁 | 当对象被销毁时才会被销毁 |
局部变量和成员变量可以重名
符合就近原则
实例方法就是类中没有static修饰的方法,添加static的叫做静态方法
符合方法的重载:同名不同参(类型,顺序,个数)
实例方法,在同一个类中,相互之间可以直接调用的
public class Demo02 {
public static void main(String[] args) {
// 在static修饰的方法中,若想调用实例方法,只能创建对象,通过对象调用
Demo02 demo02 = new Demo02();
demo02.run();
demo02.jump();
demo02.happy();
}
public void run() {
System.out.println("pao.....");
}
public void jump() {
System.out.println("tiao...");
}
public void happy() {
// 同一个类中,实例方法之间是可以直接调用的
run();
jump();
}
}
是类中特殊的方法,用于创建对象使用
作用:创建类的对象(实例化/初始化/具体化)
语法
public 类名(){
初始化代码;
}
构造方法的名字必须和类名一致
构造方法是没有返回值的,void也没有
所有的类中JVM都会自动的提供一个空的没有参数的构造方法,便于创建对象使用
一旦自定义了构造方法,系统默认的空的没有参数的构造方法就会被回收掉
类中可以有多个构造方法,一个类中的所有构造方法,只能是重载关系
public class Cat {
String name;
int age;
double weight;
public Cat() {
System.out.println("constructor...");
}
// 自定义一个参数的构造方法,用于为name进行赋值的
public Cat(String n) {
name = n;
}
public Cat(String n,int a) {
name = n;
age = a;
}
public static void main(String[] args) {
// 调用了空的构造方法,默认有jvm提供的
Cat cat = new Cat();
// 构造方法用于初始化
Cat c2 = new Cat("花花");
System.out.println(c2.name);
Cat c3 = new Cat("咪咪",2);
System.out.println(c3.name);
System.out.println(c3.age);
System.out.println(c3.weight);//没有被赋值,是默认值
}
}
1.内存中开辟对象空间
2.为各个属性赋值
3.执行构造中的代码
4.[将对象地址赋值给变量]
public class Dog {
String name;
int age;
String hobby;
public Dog(String n,int a,String h) {
System.out.println("嗨嗨嗨,我来了");
name = n;
age = a;
hobby = h;
}
public void test() {
System.out.println("heiheihei");
}
public static void main(String[] args) {
// 只要有new就会在内存中开辟地址
// 为所有的属性进行赋值(默认值 0 0.0 false '\u0000' null)
// 执行构造方法中的代码
// [可以省略]将对象的地址,赋值给变量 有一个new就有一个对象地址
// new出来才是对象(等号的右边)
// 等号的左边是变量(帮助我们给对象起一个名字,名字是可以省略的)
Dog dog = new Dog("大黄",2,"玩");
// Dog dog = new Dog();
System.out.println(dog.name);
System.out.println(dog.age);
System.out.println(dog.hobby);
dog.test();
System.out.println(new Dog("大黑",3,"睡觉").name);
new Dog("大黑",3,"睡觉").test();
}
}
含义:表示当前类的对象,调用者就this
作用:可以调用本类的属性,方法,构造方法等…
调用属性/方法时,
实例方法,调用实例属性/实例方法时,已经省略了this关键字
public class Pig {
String name;
int age;
public void run() {
System.out.println(name);
// this.调用属性可以省略
System.out.println(this.name);
}
public void jump() {
// this可以省略
this.run();
}
public Pig() {
}
public Pig(String n) {
// 省略了this
this.name = n;
}
public static void main(String[] args) {
Pig pig = new Pig();
pig.name = "佩奇";
System.out.println(pig.name);
pig.run();
}
}
当局部变量和成员变量同名,用于区分两个变量使用****(区别变量重名)
public Pig(String name,int age) {
// 就近原则
// 使用this调用的变量,就是属性
// 使用形参为成员变量赋值
this.name = name;
this.age = age;
}
调用构造时,使用特别的少…
语法
this([参数]);
指代这当前类的其他构造方法,必须在构造方法中使用,必须在构造方法的第一行使用
public class Mouse {
String name;
int age;
public Mouse() {
System.out.println("我是空构造...");
}
public Mouse(String name,int age) {
// this();就表示当前的类的其他构造方法
// 调用当前类的空构造方法
// this();
// 调用一次参数的构造方法
this("哈哈哈");
System.out.println("我是参构造");
}
public Mouse(String name) {
System.out.println("我是一个参数的构造方法");
this.name = name;//哈哈哈哈
}
// 从程序入口开始
public static void main(String[] args) {
Mouse mouse = new Mouse("贝塔",10);
}
// 普通方法的互调
public void t1() {
}
public void t2() {
t1();
}
}
包就是文件夹
作用:分类管理
之前使用的是项目中的默认包,默认包不会和其他的包有任何关联
使用英文字母,数字和点组成,数字和点不能开头结尾
点表示子包(子文件夹)
命名规则:采用域名倒置的原则,例如:www.qfetc.com 使用的包名为 com.qf.xxx
www.baidu.com 包名为com.baidu.xxx
还会根据项目,小组,功能进行包的管理
例如:com.baidu.公司名.项目名.小组名.xxx
包就是文件夹,子包就是子文件夹
自定义包:
xxx.xxx.pojo 实体类包(类模板)
xxx.xxx.vo 实体类包
xxx.xxx.dto 实体类包
xxx.xxx.dao 数据操作包
xxx.xxx.service 业务逻辑包
xxx.xxx.controller 控制层包
java中有内置包
java.lang 所java程序的语言包,默认就引入了此包
java.util 工具包,Scanner/Arrays…
java.io 文件读写包
java.sql sql操作包
…
package:声明包,必须在当前类的第一行,一个类只能有一个包的声明
import:引入另一个包中的类,一个类可以引入多个类
引入包的快捷键ctrl+shift+o(引入包和去除无用包)
// 包的声明
package com.qf.pojo;
// 引入包
import java.util.Scanner;
// 自定包中的内容,若跨包使用时也需要引入
import com.qf.test.Bcd;
// 引入String类型,但java.lang中的类是默认引入的
//import java.lang.String;
// 若引入同包中的类,无需引入包,可以手动引入,但是没必要
//import com.qf.pojo.Cat;
public class Abcd {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
new Bcd();
new Cat();
}
}
Java中的内存分配为:栈,堆,方法区,本地方法区,寄存器
字节码文件加载时,进入到内存中的方法区
方法运行区域为栈中(方法的调用)
创建的变量存储在栈中
new出来的东西,会在堆中开辟一个新的空间并产生地址
声明变量:等号的左边,在栈中
new对象:等号的右边,在堆中
基本类型和String是在栈中的
值传递:基本数据类型和String类型,都是存储在栈中的数据,传递时只传了一个值,原本的值不会发生变化
引用传递:类似于地址传值,引用类型都需要new地址,相互传递时是引用之间的变化过程,该过程会重新的分配引用
总结: ★★★★☆
基本类型和String,在方法的内部无论发生了什么,对外部不会有影响
引用类型(除String),在方法内部,只有是有了变化,对外部会造成影响
引用类型(除String),在方法内部,引用了发生了变化(new对象了),对外部没有影响