一、面向对象的初步认知
1.1 什么是面向对象
面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情,用面向对象的思想来设计程序,更符合人们对事物的认知,对于大型程序的设计、拓展以及维护都非常友好
1.2 面向对象与面向过程
面向对象只看最终结果,面向过程面对对象操作
二、类的定义和使用
2.1 简单认识类
类——描述一个对象
定义在类中的变量叫做成员变量,定义在类中的方法叫做成员方法,类是产生对象的一种抽象过程
2.2 类的定义格式
类 == 结构体 通过class自定义的类型
2.3 案例
定义一个狗类
一个Java文件只能有一个public修饰的类
代码实现
class Dog{ public String name; public String color; public int age; //行为 public void barks(){ System.out.println(name+": 旺旺旺~~~"); } public void wag(){ System.out.println(name+":摇尾巴~~~"); } }
定义一个学生类
代码实现
//定义一个学生类 public class Student { public String name; public String gender; public short age; public double score; public void DoClass(){} public void DoHomework(){} public void Exam(){} }
注意事项
1.一般一个文件当中只定义一个类
2.main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法)
3.public修饰的类必须要和文件名相同 一个Java文件只能有一个public修饰的类
4.不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改,Java文件当中只有一个类修改文件名,然后自动修改类名,若有多个类,修改类名,右键点击类,点击Refacter,点击Rename
三、类的实例化
类定义好后,由类转化为对象的过程叫做实例化
3.1 什么是实例化
将类实例化约等于定义一个结构体变量,通过关键字new实例化
由类产生对象的过程
new关键字配合类名创建对象
Dog dog1 = new Dog(); Dog dog2 = new Dog(); Dog dog3 = new Dog();
注意事项
通过引用可以拿到类中具体对象
语法:对象的引用.访问属性 进行赋值
只要new 就会产生新的对象 只要是新的对象,就有新的内存,只要通过对象的引用,去访问对象的成员变量即可或者是成员方法
我们可以通过new关键字实例化多个对象,同一个类可以产生多个实例
public static void main(String[] args) { Dog dog1 = new Dog(); dog1.name = "阿黄"; dog1.age = 4; dog1.color = "黄"; System.out.println("年龄 "+dog1.age); System.out.println("姓名 "+dog1.name); System.out.println("颜色 "+dog1.color); dog1.barks(); dog1.wag(); Dog dog2 = new Dog(); dog2.name="旺财"; dog2.color="白"; dog2.age=6; System.out.println("年龄 "+dog2.age); System.out.println("姓名 "+dog2.name); System.out.println("颜色 "+dog2.color); dog2.barks(); dog2.wag(); Dog dog3 = new Dog(); Dog dog4 = new Dog(); }
3.2 类和对象的说明
用类创建的对象都属于引用类型
数据类型:
1.基本数据类型,共8种
2.引用数据类型,String、数组、类、接口,引用类型定义的变量都是用来存对象的地址
注意:
1.引用不能指向引用,引用只能指向对象
2.一个引用同时只能指向一个对象,存储一个对象的地址
3.引用对象=null,不代表指向null对象,代表不指向任何对象
交换两个对象的值
class Myvalue{ public int val; } public static void swap(Myvalue val1,Myvalue val2){ int tmp= val1.val; val1.val= val2.val; val2.val= tmp; } Myvalue myvalue1=new Myvalue(); myvalue1.val=10; Myvalue myvalue2=new Myvalue(); myvalue2.val=20; System.out.println("交换前 "+myvalue1.val); System.out.println("交换前 "+myvalue2.val); swap(myvalue1,myvalue2); System.out.println("交换后 "+myvalue1.val); System.out.println("交换后 "+myvalue2.val);
通过类加对象进行交换两个引用数据类型的值
基本类型无法进行两个数的交换,而引用类型通过类和对象的知识对两个数进行交换
赋值案例
public class example1 { //时间类 public int year; public int month; public int day; public void setDate(int y,int m,int d){ year=y; month=m; day=d; } public void printDate(){ System.out.println("年:"+year+"月:"+month+"日:"+day); } public static void main(String[] args) { Date date=new Date(); date.setDate(1945,9,1); date.printDate(); } }
四、this引用
4.1.为什么要有this引用
1.形参名不小心与成员变量名相同
2.多个对象都在调用一个函数,但是函数内部没有任何有关对象的说明
4.2 什么是this引用
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用取访问
注意:this引用的是调用成员方法的对象
4.3 this引用的特性
代码实现
public class Date { public int year; public int month; public int day; public void setDate(int year,int month,int day){ //谁调用当前这个方法,谁就是this指向的对象 //我们建议习惯使用this this.year=year; this.month=month; this.day=day; } public void printDate(){ System.out.println(year+" 年 "+month+" 月 "+ day+" 日"); this.haha(); } public void haha(){ System.out.println("haha"); } public static void main(String[] args) { Date date=new Date(); date.setDate(1945,9,1); date.printDate(); Date date2=new Date(); date.setDate(1949,10,1); date.printDate(); } }
运行结果
注意:同一级目录(src)下,类名不可重复
五、对象的构造及初始化
对象——由类产生的实体
5.1 如何初始化对象
只有局部变量没有初始化的时候才会报错
5.2 默认初始化
所有的引用类型初始化都是null
就地初始化
在创建变量时同时给他赋值,在后续使用变量时,如果没有给他赋值,则传递一开始创建变量时给他的值作为所有变量的初始值
5.3 构造方法
构造方法(构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次,构造方法没有返回值,方法名和类名相同
构造方法的作用
对对象中的成员进行初始化,并不负责给对象开辟空间
构造方法至少有一个,也就是说当你没有写任何的构造方法的时候,编译器/Java会自带一个不带参数的构造方法,只不过默认的这个构造方法没有具体的实现
构造方法的特点
1.构造方法:特殊的方法,没有返回值,方法名和类名相同
2.对象的初始化必定会调用构造方法
3.构造方法不止一个,实例化一个对象,会调用合适的构造方法
4.构造方法必定会被调用,构造方法可以重载,一旦用户定义了构造方法,编译器不在生成,如果有构造方法,编译器不会给你提供不带参数的构造方法
5.this(...)必须是构造方法中的第一条语句
6.绝大部分构造方法用public定义,特殊场景用private初始化会报错
7.不能形成环,可以根据this来调用其他构造方法以简化代码,但不能调用循环
构造方法快捷键
Generate-->constructor
构造方法中可以用this.调用其他构造方法,节约代码量
5.4 案例 Data类
代码实现
public class Date { public int year; public int month; public int day; boolean flg; char e; public void setDate(int year,int month,int day){ //谁调用当前这个方法,谁就是this指向的对象 //我们建议习惯使用this this.year=year; this.month=month; this.day=day; } public Date(int year,int month,int day){ this.year=year; this.month=month; this.day=day; } public Date(){ /*this.year=2002; this.month=11; this.day=4;*/ this(2002,11,04);//用this传递构造方法时,必须放在方法内部第一行 //不能形成环 绝大部分构造方法用public定义,特殊场景用private初始化会报错 System.out.println("执行了不带参数的构造方法......"); } public void printDate(){ System.out.println(year+" 年 "+month+" 月 "+ day+" 日"); //this.haha(); } public void haha(){ System.out.println("haha"); } public static void main(String[] args) { Date date=new Date(); //不带参数的构造方法,系统设置初值 System.out.println(date.day);//4 System.out.println(date.month);//11 System.out.println(date.year);//2002 System.out.println(date.e);//空字符 System.out.println(date.flg);//false System.out.println(); //默认值2002年11月4日 date.printDate(); //setdate赋值构造方法 date.setDate(1945,9,1); date.printDate(); System.out.println(); //不带参数的构造方法 Date date2=new Date(); //setdate赋值构造方法 date.setDate(1949,10,1); date.printDate(); System.out.println(); //赋予三个初值的date方法 Date date3=new Date(1995,11,18); date3.printDate(); //构造方法快捷键 //Generate-->constructor //构造方法中可以用this调用其他构造方法 } }
运行结果
总结
六、封装 private
加上private,代表这个方法只能在当前类中使用
面向对象的几个重要的特征:封装、继承、多态
Java、C++
6.1.封装的概念
封装:套壳屏蔽细节
封装:屏蔽类的实现细节,对外只提供一些开放的接口
为何要封装?安全考虑,更能体现类的安全性,提升安全性
构造方法也可以被封装,封装后只能在当前类中使用
案例
name是private修饰,所以只能在当前类中使用
class Student1{ //当private修饰当前变量时,当前变量只能在当前类中使用 private String name; //实现封装后,类外无法直接拿到字段但是可以通过一些方法 public int age; //构造方法 也可以被封装 封装后方法只能在当前类中使用 public Student1(String name,int age){ this.name=name; this.age=age; } public void setName(String name){ this.name=name; } public String getName(){ return this.name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public void eat(){ System.out.println(this.name+"正在吃饭!"); } } //封装是对类的实现细节进行隐藏,类外无法使用封装细节 public class day_14 { public static void main(String[] args) { Student1 student=new Student1("张三",10); //private实现封装情况,在封装后,当前方法只能在当前类中使用 //封装 隐藏eat方法 student.setName("小王"); System.out.println(student.getName()); student.eat(); } }
主要使用private对于类中的变量及方法进行限制,使得类中的方法和变量被限制后无法在类之外使用,大大提升了程序的安全性
6.2 访问修饰限定符
1.public 公开的 在哪里都能被访问到
2.protected 受保护的
3.default 没有default这个权限,代表默认情况下,什么都不写
4.private 私人的 只能在当前类中使用
说明
6.3 封装拓展之包
6.3.1 包的概念
为了更好地管理类,把多个类收集在一起成为一组,称为软件包,多个类放在一起称为一个包
package 包名.包名. ...所有的包名中
6.3.2 自定义包
package+包名
6.3.3 导入包中的类
可以使用java.包名.类名,导入util这个包中的Date类,使用import语句直接导入包
ALT+enter 快捷键显示存在哪个包中
import java.包名.* ;通配,要用哪个包就直接导入哪个包
可以用import static导入包中静态的方法和字段
static修饰的方法可以直接用方法名调用
包≈文件夹,类≈文件
6.3.4 包的访问权限控制
6.3.5 常见的包
一般常见的包会由Java自动导入
七.static成员关键字
静态成员
7.1 static修饰静态成员变量特性
1.不属于某个具体的对象,是类的属性,所有对象共享,不存储在某个对象的空间中
2.既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
3.类变量存储在方法区当中
4.生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)
静态成员变量≈在当前类中使用的全局变量,静态的只能是成员变量,不能是局部变量
7.2 static修饰方法
在静态方法内部,不能使用非静态的数据成员
this不能出现在静态方法内部当中
静态方法特性
4.静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用
5.静态方法无法重写,不能用来实现多态
总结
静态变量也称为类变量,在类的对象之间通用,并且也可以使用类名来访问此变量
非静态变量又称实例变量
1.静态成员函数不能访问非静态变量
2.非静态变量特定于创建它们的实例对象
3.非静态变量可能会占有更多空间,内存分配可能在运行时发生
4.普通变量不需要具有任何特殊的关键字
静态的成员变量与非静态的成员变量的区别:
1. 作用上的区别:
1. 静态的成员变量的作用共享一个 数据给所有的对象使用。.
非静态的成员变量的作用是描述一类事物的公共属性。
2. 数量与存储位置上的区别:
1. 静态成员变量是存储方法 区内存中,而且只会存在一份数据。\非静态的成员变量是存储在堆内存中,有n个对象就有n份数据。
3. 生命周期的区别:
1. 静态的成员变量数据是随着类的加载而存在,随着类文件的消失而消失。
2.非静态的成员数据是随着对象的创建而存在,随着 对象被垃圾回收器回收而消失。
八、代码块
8.1 代码块概念以及分类
使用{}定义的一段代码称为代码块有根据定义位置及关键字分为
1.普通代码块
2.构造代码块
3.静态代码块
4.同步代码块
8.2 普通代码块
{ },定义在方法当中的代码块,执行不需要条件,永远会被执行
8.3 构造代码块
定义在方法外部类内部
叫做构造代码块或实例代码块
一般用来初始化非静态的数据成员
8.4 静态代码块
static修饰的代码块,一般用于初始化静态成员变量
初始化静态成员变量
静态代码块一定最先被执行,其次是实例代码块,静态代码块不依赖对象
如果都是静态的,则观察定义的顺序来决定执行的顺序
注意事项
1、静态代码块不管生成多少个对象,其都只会执行一次
2.静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
3.如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
4.实例代码块只有在创建对象时才会执行
过一内容
package com.bit.www.Test; class DogP{ private String name; private int age; private String color; //构造方法,用来实例化 public DogP(String name,int age,String color){ this.name=name; this.age=age; this.color=color; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void barks(){ System.out.println(this.name+"正在汪汪叫"); } public void eat(){ System.out.println(this.name+"正在吃狗粮"); } public void staticFun(){ System.out.println("staticFun......"); } public void show(){ System.out.println("狗名:"+this.name+"年龄:"+this.age+"颜色"+this.color); } } public class ts { public static void main(String[] args) { DogP dog=new DogP("旺财",3,"白色"); dog.setAge(4); dog.setColor("黄色"); dog.eat(); dog.barks(); //com.bit.www.Test.DogP@1554909b类型所在的地址 System.out.println(dog); dog.show(); } }