接上期JAVA初级笔记(14-17)
18、面向对象(1)
1、面向过程与面向对象的区别:
1)、面向过程:(考虑怎么做)------->编年体
当事情比较简单的时候,可以利用面向过程,注重的事件的具体步骤/过程,注重的是过程中的具体的行为,以函数为最小的单位。
2)、面向对象:(考虑谁来做)-------->纪传体
注重找“参与者”,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位。
3)、案例:(人将大象装进冰箱)
面向过程:
函数1:打开冰箱(){人站在冰箱前,打开冰箱,冰箱卡到25度角的时候,冰箱的灯打开了…}
函数2:储存大象(){大象先迈左腿,再迈右退,考虑冰箱能不能装下…}
函数3:关闭冰箱(){人站在冰箱前,关闭冰箱,冰箱开到25度角的时候,冰箱的灯关闭了…}
面向对象:(参与者:人、大象、冰箱)
人{
打开(冰箱){
冰箱.打开();
}
存储(大象){
大象.进入();
}
关闭(冰箱){
冰箱.关闭();
}
}
冰箱{
打开(){ 1.2.3.}
关闭(){}
}
大象{
进入(冰箱){
}
}
注:
面向过程 —> 面向对象 , 其实就是由执行者 —> 指挥者的 一个过渡
二者相辅相成,并不是对立的。解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系、方便我们分析整个系统;具体到微观操作,仍然使用面向过程方式来处理
2、类和对象的关系
(1)、万事万物皆对象
(2)、
对象:具体的事物,具体的实体,具体的实例,模板下具体的产品
类:对对象向上抽取出像的部分,公共的部分,形成类,类是抽象的,是一个模板
(3)、一般在写代码的时候先写类,然后在根据类创建对应的对象。
3、面向对象的三个阶段
面向对象三个阶段:(分析---->设计---->编程)
(1)面向对象分析OOA : (Object Oriented Analysis)
找到参与者------->对象------>抽取出一个类
如:
对象:狮子,老虎,猴子,大象,蛇
类:动物(Animal)
类里面有什么:
动词----->动态特性----->方法(做某一具体的事,实现某一具体的功能,都是动作)
名词----->静态特性----->属性(age、name、height、weight)
(2)面向对象设计OOD: (Object Oriented Design)
先有类,再有对象:
类:动物:Animal
对象:狮子,老虎,猴子,大象,蛇
(3)面向对象编程OOP : (Object Oriented Programming)
4、创建类
public class Person {
//1、名词---》属性---》成员变量---》放在类中方法外(注意:我们只把有需要的内容写到代码里,不相关的东西不要放在代码中)
int age ;//年龄
String name;//姓名
double height;//身高
double weight;//体重
//2、动词---》方法
//吃饭
public void eat(){
int num = 10;//局部变量:放在方法中
System.out.println("我喜欢吃饭");
}
//睡觉:
public void sleep(String address){
System.out.println("我在"+address+"睡觉");
}
//自我介绍:
public String introduce(){
return "我的名字是:"+name+",我的年龄是:"+age+",我的身高是:"+height+",我的体重是:"+weight;
}
}
创建类:
(1)属性(field 成员变量)
属性用于定义该类或该类对象包含的数据或者说静态特征。属性作用范围是整个类体。
属性的语法结构
[修饰符] 属性类型 属性名 = [默认值] ;
(2)方法的语法结构:
方法用于定义该类或该类实例的行为特征和功能实现。方法是类和对象行为特征的抽象。方法很类似于面向过程中的函数。面向过程中,函数是最基本单位,整个程序由一个个函数调用组成。面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。
方法语法结构:
[修饰符] 方法返回值类型 方法名(形参列表) {
n条语句
}
注:
void代表没有返回值;方法的作用:重用代码,封装功能,便于修改
5、创建对象
public class Test {//测试类
//这是一个main方法,是程序的入口:
public static void main(String[] args){
//创建一个人类的具体的对象/实例:
//创建一个对象,对象的名字叫:b
//Person 属于 引用数据类型
//第一次加载类的时候,会进行类的加载,初始化创建对象的时候,对象的属性没有给赋值,有默认的初始化的值。
Person b = new Person();
b.name ="强强";
b.age = 25;
b.height = 170;
b.weight = "55kg";
//再创建一个对象:
//再次创建类的时候,就不会进行类的加载了,类的加载只在第一次需要的时候加载一次
Person a = new Person();
a.name ="花花";
a.age = 23;
a.height = 169;
a.weight = "55kg";
//对属性值进行读取:
System.out.println(b.name);
System.out.println(a.name);
//对方法进行操作:
//不同的对象,属性有自己的特有的值,但是方法都是调用类中通用的方法。
//属性:各个对象的属性是独立的,
//方法:各个对象的方法是共享的。
b.eat();
a.eat();
b.sleep("教室");
/* String str =s.introduce();
System.out.println(str);
*/
//可以合成一句话:
System.out.println(b.introduce());
}
}
语法结构:
6、局部变量与成员变量的区别
public class Student {
//成员变量:在类中方法外
byte e;
short s;
int c ;
long num2;
float f ;
double d;
char ch;
boolean bo;
String name;
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
Student s = new Student();'\n0000'/null
System.out.println(s.c);//0
System.out.println(s.bo);//false
System.out.println(s.ch);//
System.out.println(s.d);//0.0
System.out.println(s.e);//0
System.out.println(s.f);//0.0
System.out.println(s.name);//null
System.out.println(s.num2);//0
System.out.println(s.s);//0
s.d = 10.4;//赋值
}
public void study(){//方法:
int num = 10 ; //局部变量:在方法中
System.out.println(num);//10
//int num ;重复命名,出错了
{
int a;//局部变量:在代码块中
}
int a;
if(1==3){
int b;
}
System.out.println(c);
}
public void eat(){//方法:
System.out.println(c);
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.c);//0
System.out.println(s.bo);//false
System.out.println(s.ch);//
System.out.println(s.d);//0.0
System.out.println(s.e);//0
System.out.println(s.f);//0.0
System.out.println(s.name);//null
System.out.println(s.num2);//0
System.out.println(s.s);//0
s.d = 10.4;//赋值
}
}
区别:
1:代码中位置不同
成员变量:类中方法外定义的变量
局部变量:在方法中定义的变量 在代码块中定义的变量
2:代码的作用范围
成员变量:当前类的很多方法
局部变量:当前一个方法(当前代码块)
3:是否有默认值
成员变量:有
局部变量:没有
基本数据类型:看程序中
引用数据类型: null
4:是否要初始化
成员变量:不需要,不建议初始化,后续使用的时候再赋值即可
局部变量:一定需要,不然直接使用的时候报错
5:内存中位置不同
成员变量:堆内存
局部变量:栈内存
6:作用时间不同
成员变量:当前对象从创建到销毁
局部变量:当前方法从开始执行到执行完毕
7、构造器
public class Person {
//构造器:没有任何参数的构造器我们叫做:空参构造器--》空构造器
public Person(){
/*age = 19;
name = "huahua";
height = 169.5;*/
}
//属性:
String name;
int age;
double height;
//方法:
public void eat(){
System.out.println("我喜欢吃饭");
}
}
public class Test {//测试
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
//创建一个Person类的具体的对象/实例/实体:
/*
创建对象的过程:
1.第一次遇到Person的时候,进行类的加载(只加载一次)
2.创建对象,为这个对象在堆中开辟空间
3.为对象进行属性的初始化动作
new关键字实际上是在调用一个方法,这个方法叫构造方法(构造器)
调用构造器的时候,如果你的类中没有写构造器,那么系统会默认给你分配一个构造器,只是我们看不到罢了。
可以自己显式 的将构造器编写出来:
*/
Person p = new Person();
System.out.println(p.age);
System.out.println(p.name);
System.out.println(p.height);
Person p2 = new Person();
System.out.println(p2.age);
System.out.println(p2.name);
System.out.println(p2.height);
}
}
1、 构造器语法结构:
= [修饰符] 构造器的名字(){
}
2、构造器和方法的区别:
1.没有方法的返回值类型
2.方法体内部不能有return语句
3.构造器的名字很特殊,必须跟类名一样
3、构造器的作用:
不是为了创建对象,因为在调用构造器之前,这个对象就已经创建好了,并且属性有默认的初始化的值。
调用构造器的目的是给属性进行赋值操作的。
注意:
我们一般不会在空构造器中进行初始化操作,因为那样的话每个对象的属性就一样了。实际上,我们只要保证空构造器的存在就可以了,里面的东西不用写
写属性、方法、构造器时顺序不是固定的
8、构造器重载
public class Person {
//属性:
String name;
int age;
double height;
//空构造器
public Person(){
}
public Person(String name,int age,double height){
//当形参名字和属性名字重名的时候,会出现就近原则:
//在要表示对象的属性前加上this.来修饰 ,因为this代表的就是你创建的那个对象
this.name = name;
this.age = age;
this.height = height;
}
public Person(String a,int b){
name = a;
age = b;
}
//方法:
public void play(){
System.out.println("我喜欢打篮球");
}
}
public class Test {
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
/*
1.一般保证空构造器的存在,空构造器中一般不会进行属性的赋值操作
2.一般我们会重载构造器,在重载的构造器中进行属性赋值操作
3.在重载构造器以后,假如空构造器忘写了,系统也不会给你分配默认的空构造器了,那么你要调用的话就会出错了。
4. 当形参名字和属性名字重名的时候,会出现就近原则:
在要表示对象的属性前加上this.来修饰 ,因为this代表的就是你创建的那个对象
*/
Person p = new Person();
/*p.age = 19;
p.name = "lili";
p.height = 180.4;*/
Person p2 = new Person("lili",19,180.4);
System.out.println(p2.age);
System.out.println(p2.height);
System.out.println(p2.name);
}
}
9、this
this可以修饰属性:
public class Person {
//属性
int age;
String name;
double height;
//空构造器
public Person(){
}
//有参构造器
public Person(int age,String name,double height){
this.age = age;
this.name = name;
this.height = height;
}
//方法:
public void eat(){
int age = 10;
System.out.println(age);//就近原则,age指的是离它近的age--》局部变量的age
System.out.println(this.age);//这里指代的就是属性的age
System.out.println("我喜欢吃饭");
}
}
this修饰方法:
public class Person {
//属性
int age;
String name;
double height;
//空构造器
public Person(){
}
//有参构造器
public Person(int age,String name,double height){
this.age = age;
this.name = name;
this.height = height;
}
//方法:
/*public void eat(){
int age = 10;
System.out.println(age);//就近原则,age指的是离它近的age--》局部变量的age
System.out.println(this.age);//这里指代的就是属性的age
System.out.println("我喜欢吃饭");
}*/
public void play(){
/*this.*/eat();
System.out.println("上网");
System.out.println("洗澡");
}
public void eat(){
System.out.println(/*this.*/age);
System.out.println("吃饭");
}
}
this可以修饰构造器:
public class Person {
//属性
int age;
String name;
double height;
//空构造器
public Person(){
}
//有参构造器
public Person(int age,String name,double height){
this(age,name);
this.height = height;
}
public Person(int age,String name){
this(age);
this.name = name;
}
public Person(int age){
this.age = age;
}
this关键字 用法:
(1)this可以修饰属性:
总结:当属性名字和形参发生重名的时候,或者 属性名字 和局部变量重名的时候,都会发生就近原则,所以如果我要是直接使用变量名字的话就指的是离的近的那个形参或者局部变量,这时候如果我想要表示属性的话,在前面要加上:this.修饰
如果不发生重名问题的话,实际上你要是访问属性也可以省略this.
(2)this修饰方法:
总结:在同一个类中,方法可以互相调用,this.可以省略不写。
(3)this可以修饰构造器:
总结:同一个类中的构造器可以相互用this调用,注意:this修饰构造器必须放在第一行
语法结构:
this(形参名);
10、static修饰属性
public class Test {
//属性:
int id;
static int sid;
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
//创建一个Test类的具体的对象
Test t1 = new Test();
t1.id = 10;
t1.sid = 10;
Test t2 = new Test();
t2.id = 20;
t2.sid = 20;
Test t3 = new Test();
t3.id = 30;
t3.sid = 30;
//读取属性的值:
System.out.println(t1.id);
System.out.println(t2.id);
System.out.println(t3.id);
System.out.println(t1.sid);
System.out.println(t2.sid);
System.out.println(t3.sid);
}
}
内存分析:
一般官方的推荐访问方式:可以通过类名.属性名的方式去访问
public class MsbStudent {
//属性:
String name;
int age;
static String school;
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
MsbStudent.school = "墨子学院";
//创建学生对象:
MsbStudent s1 = new MsbStudent();
s1.name = "张三";
s1.age = 19;
//s1.school = "墨子学院";
MsbStudent s2 = new MsbStudent();
s2.name = "李四";
s2.age = 21;
//s2.school = "墨子学院";
System.out.println(s2.school);
}
}
1、static可以修饰:属性,方法,代码块,内部类。
2、static修饰属性总结:
(1)在类加载的时候一起加载入方法区中的静态域中
(2)先于对象存在
(3)访问方式:对象名.属性名 / 类名.属性名(推荐)
3、static修饰属性的应用场景:某些特定的数据想要在内存中共享,只有一块 --》这个情况下,就可以用static修饰的属性
4、属性:
静态属性 (类变量)
非静态属性(实例变量)
11、static修饰方法
public class Demo {
int id;
static int sid;
public void a(){
System.out.println(id);
System.out.println(sid);
System.out.println("------a");
}
//1.static和public都是修饰符,并列的没有先后顺序,先写谁后写谁都行
static public void b(){
//System.out.println(this.id);//4.在静态方法中不能使用this关键字
//a();//3.在静态方法中不能访问非静态的方法
//System.out.println(id);//2.在静态方法中不能访问非静态的属性
System.out.println(sid);
System.out.println("------b");
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
//5.非静态的方法可以用对象名.方法名去调用
Demo d = new Demo();
d.a();
//6.静态的方法可以用 对象名.方法名去调用 也可以 用 类名.方法名 (推荐)
Demo.b();
d.b();
b();
//7.在同一个类中可以直接调用
}
}
1.static和public都是修饰符,并列的没有先后顺序,先写谁后写谁都行
2.在静态方法中不能访问非静态的属性
3.在静态方法中不能访问非静态的方法
4.在静态方法中不能使用this关键字
5.非静态的方法可以用对象名.方法名去调用
6.静态的方法可以用 对象名.方法名去调用 也可以 用 类名.方法名 (推荐)
7.在同一个类中可以直接调用
12、代码块
public class Test {
//属性
int a;
static int sa;
//方法
public void a(){
System.out.println("-----a");
{
//普通块限制了局部变量的作用范围
System.out.println("这是普通块");
System.out.println("----000000");
int num = 10;
System.out.println(num);
}
//System.out.println(num);
//if(){}
//while(){}
}
public static void b(){
System.out.println("------b");
}
//构造块
{
System.out.println("------这是构造块");
}
//静态块
static{
System.out.println("-----这是静态块");
//在静态块中只能访问:静态属性,静态方法
System.out.println(sa);
b();
}
//构造器
public Test(){
System.out.println("这是空构造器");
}
public Test(int a){
this.a = a;
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
Test t = new Test();
t.a();
Test t2 = new Test();
t2.a();
}
}
1、类的组成:属性,方法,构造器,代码块,内部类
2、代码块分类:普通块,构造块,静态块,同步块(多线程)
3、注:
1)、普通块限制了局部变量的作用范围
2)、构造块在方法外
3)、在静态块中只能访问:静态属性,静态方法
总结:
(1)代码块执行顺序:
最先执行静态块,只在类加载的时候执行一次,所以一般以后实战写项目:创建工厂,数据库的初始化信息都放入静态块。
一般用于执行一些全局性的初始化操作。
再执行构造块,(不常用)
再执行构造器,
再执行方法中的普通块。
13、包_import_(1)
1、包的作用:
为了解决重名问题(实际上包对应的就是盘符上的目录)
解决权限问题
2、创建包:
包名定义:
(1)名字全部小写
(2)中间用.隔开
(3)一般都是公司域名倒着写 : com.jd com.msb
(4)加上模块名字:
com.jd.login com.jd.register
(5)不能使用系统中的关键字:nul,con,com1—com9…
(6)包声明的位置一般都在非注释性代码的第一行:
3、导包问题:
//声明包:
package com.msb7;
import com.msb2.Person; //导包:就是为了进行定位
import java.util.Date;
/**
* @Auther: msb-zhaoss
*/
public class Test {
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
new Person();
new Date();
new java.sql.Date(1000L);//在导包以后,还想用其他包下同名的类,就必须要手动自己写所在的包。
new Demo();
}
}
总结:
(1)使用不同包下的类要需要导包: import **..; 例如:import java.util.Date;
(2)在导包以后,还想用其他包下同名的类,就必须要手动自己写所在的包。
(3)同一个包下的类想使用不需要导包,可以直接使用。
(4)在java.lang包下的类,可以直接使用无需导包:
(5)IDEA中导包快捷键:alt+enter
可以自己设置自动导包
(6)可以直接导入*:
14、包_import_(2)
1、在Java中的导包没有包含和被包含的关系:
设置目录平级的格式(不是包含和被包含的显示):
2、静态导入:
package com.msb11;
//静态导入:
import static java.lang.Math.*;
//导入:java.lang下的Math类中的所有静态的内容
/**
* @Auther: msb-zhaoss
*/
public class Test {
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
System.out.println(random());
System.out.println(PI);
System.out.println(round(5.6));
}
//在静态导入后,同一个类中有相同的方法的时候,会优先走自己定义的方法。
public static int round(double a){
return 1000;
}
}