面向对象
把具有相同特征和操作的实体(事物)归为一类
类相当于是一个模板,刻画出具有相同特征和操作的实体(事物)
类
tips:
1.类中只有属性(特征)和方法(操作)。
2.属性是全局变量,分为成员变量和静态变量。
3.方法也分为成员方法和静态方法。
public class 类名{
//属性也叫做全局变量,分为成员变量和静态变量
//成员变量
数据类型 变量名;
//静态变量
static 数据类型 变量名;
//方法分为成员方法和静态方法
//成员方法
访问修饰符 返回值类型 方法名([参数]){}
//静态方法
访问修饰符 static 返回值类型 方法名([参数]){}
}
public class Test{
public static void main(String[] args){
//创建对象
类名 引用=new 类名();
//调用成员变量和成员方法
引用.成员变量;
引用.成员方法;
//调用静态变量和静态方法
类名.静态变量;
类名.静态方法;
}
}
对象:
创建对象语法:
类名 对象(引用)=new 类名();
tips: 1.对象又称为引用,存放对象地址。
2.类名():为类的无参构造方法,后面还会学习有参构造方法。
对象可以操作的内容:
1.设置成员属性;eg: p.name=“OYO”;
2.获取成员属性;eg: System.out.println(p.name);
3.调用成员方法;eg: p.sleep();
成员属性/成员变量:
成员属性/成员变量:
系统会赋默认值,位于对应的类中,且不声明于方法里,作用于整个类中。(类里,方法的外面)
声明:
数据结构 变量名;
局部变量:方法内的变量,系统不会赋默认值,要初始化之后才能使用,作用于其域中。
成员方法:
成员方法:编写于对应的类中,属于对象的方法,必须使用对象调用。
语法结构: 访问修饰符 返回值类型 方法名([参数]){ }
静态方法:属于类的方法,使用类名调用。
创造对象:
public class Person {
/**成员属性/成员变量
*注意:属于对象的变量,系统会赋默认值,该类的所有的成员方法都能使用该变量。
*成员变量的默认值:
* 整数类型:0
* 浮点类型:0.0
* 字符类型:' '
* 布尔类型:false
* 引用类型:null
*/
String name;
char sex;
int age;
//方法
public void eat(){
//局部变量:方法里面的变量,必须初始后才能使用,其作用域在该方法内
int i=100;
System.out.println("吃饭饭!");
}
public void sleep(){
System.out.println("睡觉觉!");
}
//静态方法
//静态方法中不能使用成员变量
public static void method(){
System.out.println("运行静态方法!");
}
}
package com.qf.test01;
public class Test01 {
public static void main(String[] args) {
//创建Person类的对象
Person p = new Person();
//设置对象的属性
p.name="OYO";
p.sex='女';
p.age=21;
//获得对象的属性
System.out.println(p.name);
System.out.println(p.sex);
System.out.println(p.age);
//调用方法
//调用成员方法:使用引用/对象来调用成员方法
p.eat();
p.sleep();
//调用静态方法:使用类名来调用方法
Person.method();
}
}
tips:
1.先创建Person类,属性、方法。
2.再创建Person类的对象。
创建多个对象
public class Test01 {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
p1.name="OYO";
p1.sex='女';
p1.age=21;
p2.name="文静";
p2.sex='女';
p2.age=21;
p1.eat();
p1.sleep();
p2.eat();
p2.sleep();
Person.method();
}
}
package com.qf.test01;
public class Person {
//成员变量
String name;
char sex;
int age;
//成员方法
public void eat(){
System.out.println(this.name+"吃饭饭!");
}
public void sleep(){
System.out.println(this.name+"睡觉觉!");
}
//静态方法
public static void method(){
System.out.println("静态方法");
}
}
总结:
1.每个class文件在内存中只加载一次。
2. class文件中包含了该类的所有信息。
3. new对象会在堆里面开辟空间,存放该对象的成员变量。
4.系统会给成员变量赋默认值。
5.每个对象独享一份成员变量。
6.成员方法中可以使用this。
7.方法中的this表示调用该方法的对象。
8.静态方法使用类名调用,所以方法内不能使用this。
9.成员方法在.class文件中,调用时才在栈里开辟空间。
构造方法:
构造方法:没有返回项且与类名相同的方法。
作用: 1.和new关键字一起表示创建对象(实例化)
2.初始化数据
分类:有参构造函数和无参构造函数。(有有参构造函数的时候,一定要写无参构造函数。没有有参构造函数时,系统会默认实现无参构造函数)
tips: 1.创建对象(对象实例化)语法:类型 引用=new 构造函数。
2.当类中没有 有参构造 时,系统会默认实现 无参构造。
public class Person1 {
//属性
String name;
char sex;
int age;
//无参构造函数:无返回项且与类名相同
public Person1(){
System.out.println("无参构造函数运行!");
//设置默认值
//this表示当前对象
this.name="OYO";
this.sex='女';
this.age=18;
}
//有参构造函数:有有参构造函数,就一定要写无参构造函数
public Person1(String name,char sex, int age){
System.out.println("有参构造函数运行");
//初始化数据
this.name=name;
this.sex=sex;
this.age=age;
}
//成员方法
public void eat(){
System.out.println(this.name+"吃饭饭!");
}
public void sleep(){
System.out.println(this.name+"睡觉觉!");
}
//静态方法
public static void method(){
System.out.println("静态方法");
}
}
public class test01 {
public static void main(String[] args) {
//和new关键字一起表示创建对象(实例化)
Person1 p1 = new Person1("巴卫",'男',188888);
System.out.println(p1.name);
System.out.println(p1.sex);
System.out.println(p1.age);
p1.eat();
p1.sleep();
Person1.method();
}
}
private关键字:
private----->私有化
private是访问修饰符的一种,访问修饰符规定访问权限
作用: 1.修饰属性:私有化属性,只能在该类的内部使用
2.修饰方法:私有化方法,只能在该类的内部使用
应用场景:不让让外界访问的属性和方法就用private修饰
封装
步骤:
1. 私有化属性
2. 添加get(获取属性)/set(设置属性)方法
好处:外界不可以直接操作属性(有风险),必须通过get、set方法操作,可以在get、set方法中做额外的功能
package com.qf.test02;
import java.time.LocalDateTime;
public class User {
String username;
String password;
String name;
private double surplus;//余额
public User() {
}
public User(String username, String password, String name, double surplus) {
this.username = username;
this.password = password;
this.name = name;
this.surplus = surplus;
}
//设置余额
public void setSurplus(double surplus){
//额外的功能,显示操作该步骤的时间
double num = (surplus - this.surplus);
System.out.println(LocalDateTime.now() + " -- " + this.name + "用户操作了金额:" + ((num>0)?"+":"") + num);
//设置属性
this.surplus = surplus;
}
//获取余额
public double getSurplus(){
//额外的功能
System.out.println(LocalDateTime.now() + " -- " + this.name + "用户获取了金额");
//返回余额
return surplus;
}
}
//模拟银行用户操作余额的功能
public class Test01 {
public static void main(String[] args) {
User user = new User("username1111", "123123", "OYO", "12345678901", '女', 100);
//存钱
user.setSurplus(user.getSurplus() + 200);
//取钱
user.setSurplus(user.getSurplus() -180);
//查看
System.out.println(user.getSurplus());//120
}
}
This:
this:代表本对象,this出现方法里,表示调用该方法的对象(哪个对象调用该方法,该方法里的this就表示该对象)。
this的使用:
- this.属性:调用本对象的成员变量
- this.方法:调用本对象的成员方法
- this():调用本对象的构造方法(在一个构造方法中的第一句调用另外一个构造方法)
static (静态):
作用:
1.修饰属性:
类加载到方法区时,JVM会扫描该类的所有属性并把静态属性加载到静态区中,静态属性属于类属性,该类所有的对象都共享该属性静态属性直到项目结束时才会被回收。
注意:静态属性使用类名调用。
2.修饰方法:
属于类方法,直接用类名调用(eg:工具类)
3.静态代码块:
静态代码块是类加载到方法区时才会被调用,该代码块只能初始化静态变量。
代码块是创建对象时优先于构造方法调用,该代码块可以初始化成员变量和静态变量。构造方法是创建对象时调用,该方法可以初始化成员变量和静态变量。
静态属性:
成员变量和静态变量区别:
成员变量:属于对象的变量,每个对象独享一份。
静态变量:属于类的变量,每个对象都共享一份。
静态属性何时创建:
使用到类, JVM虚拟机 会判断方法区中是否有该类的class文件,如果没有,就把该类的class文件加载到方法区。JVM扫描该类class文件,收集该类的所有信息,并把静态属性添加到静态区中。(1. 开辟空间 2.赋系统默认值)
静态属性何时销毁: 项目结束时,静态属性才会被销毁(静态属性的生命周期很长,使用需谨慎)
静态属性的应用场景:
该类所有的对象需要共享的属性,就可以设置为静态。
静态方法:
成员方法 和 静态方法区别:
成员方法:必须使用对象调用,也就是说调用成员方法之前必须创建对象(开辟空间)
静态方法:属于类的方法,直接使用类名调用,纯功能的方法就可以设计成静态方法(工具类),比如Arrays工具类
//自己编写的Arrays工具类(全是静态方法)
public class Arrays {
/**
* 数组的排序
* @param a 需要排序的数组
*/
public static void sort(int[] a){
//使用冒泡排序
//数组元素N,外层循环N-1,内层循环N-1-i
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-1-i;j++){
if(a[j]>a[j+1]){
//大的元素值往后排
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
/**
* 数组的二分查找(必须先排好序,再查找)
* @param a 需要查找的数组
* @param key 需要查找的值
* @return 如果搜索的元素包含在数组中就返回元素的下标; 否则,返回(-插入点-1)
*/
public static int binarySearch(int[]a,int key){
//二分查找
int start=0;
int end=a.length-1;
while(start<=end){
int mid=(start+end)/2;
if(key>a[mid]){
start=mid+1;
}else if(key<a[mid]){
end=mid-1;
}else{//key的值等于a[mid]
return mid;
}
}
//没有找到相应的元素
return (-start-1);
}
/**
* 拷贝数组
* @param original 被拷贝的数组
* @param newLength 新数组的长度
* @return 新数组
*/
public static int[] copyOf(int[] original,int newLength){
//新数组的长度可以比原数组长,也可以比原数组短
int copyLength=original.length;
//如果新数组的长度比原数组的短
if(copyLength>newLength){
copyLength=newLength;
}
int[] newArr=new int[newLength];
for(int i=0;i<copyLength;i++){
newArr[i]=original[i];
}
return newArr;
}
/**
* 拷贝区间数组
* @param original 被拷贝的数组
* @param from 开始下标(包含)
* @param to 结束下标(排他)
* @return 新数组
*/
public static int[] copyOfRange(int[] original,int from,int to){
int newLength=to-from;
int[] newArr=new int[newLength];
int index=0;//递增变量
for(int i=from;i<to;i++){
newArr[index++]=original[i];
}
return newArr;
}
/**
* 替换数组元素
* @param a 被替换数组
* @param val 替换的值
*/
public static void fill(int[] a, int val){
// for(int i=0;i<a.length-1;i++){
// a[i]=val;
// }
fill(a,0,a.length,val);
}
/**
* 替换区间数组元素
* @param a 被替换数组
* @param fromIndex 开始下标(包含)
* @param toIndex 结束下标(排他)
* @param val 替换的值
*/
public static void fill(int[] a, int fromIndex,int toIndex,int val){
for(int i=fromIndex;i<toIndex;i++){
a[i]=val;
}
}
/**
* 将数组转换为字符串
* @param a 被转换的数组
* @return 转换后的字符串
*/
public static String toString(int[] a){
String str="[";
for(int i=0;i<a.length;i++){
if(str.length()!=1){
str+=",";
}
str+=a[i];
}
str+="]";
return str;
}
}
静态代码块:
代码块:创造对象时优先于构造方法调用
静态代码块:class文件加载到方法区时调用
package com.qf.test06;
public class A {
String str1;//成员属性
static String str2;//静态属性
//静态代码块作用:操作静态属性,不能操作成员属性
static{
A.str2 = "eee";//底层实现:A.str2 = "eee";
System.out.println("静态代码块 --" + A.str2);
}
//代码块作用:操作成员属性和静态属性
{
str1 = "ccc";//底层实现:this.str1 = "ccc";
str2 = "ddd";//底层实现:A.str2 = "ddd";
System.out.println("代码块-- " + str1 + " -- " + str2);
}
//构造方法作用:操作成员属性和静态属性
public A() {
str1 = "aaa";//底层实现:this.str1 = "aaa";
str2 = "bbb";//底层实现:A.str2 = "bbb";
System.out.println("构造方法 -- " + str1 + " -- " + str2);
}
}
tips:
1.创建对象时,在构造方法中初始化数据
2.项目中可以在静态代码块中初始化静态属性