Java入门——面向对象详解
面向对象的三大特征封装继承多态所有面向对象的编程语言都有这三大特征采用面向对象的方式开发一个软件,生命周期当中:【整个生命周期中贯穿使用OO面向对象方式】面向对象的分析:OOA面向对象的设计:OOD面向对象的编程:OOP类和对象的概念什么是类?类在现实世界中是不存在的,是一个模板,是一个概念,是人类大脑思考抽象的结果。类代表了一类事物在现实世界中,对象A与对象B之间具有共同特征,进行抽象总结出一个
面向对象的三大特征
封装
继承
多态
所有面向对象的编程语言都有这三大特征
采用面向对象的方式开发一个软件,生命周期当中:【整个生命周期中贯穿使用OO面向对象方式】
面向对象的分析:OOA
面向对象的设计:OOD
面向对象的编程:OOP
类和对象的概念
什么是类?
类在现实世界中是不存在的,是一个模板,是一个概念,是人类大脑思考抽象的结果。
类代表了一类事物
在现实世界中,对象A与对象B之间具有共同特征,进行抽象总结出一个模板,这个模板被称为类。
什么是对象?
对象是实际存在的个体。现实世界当中实际存在。
描述一下整个软件开发的过程:
程序员先观察现实世界,从现实世界中寻找对象
寻找了N多个对象之后,发现所有的对象都有共同特征
程序员在大脑中形成了一个模板【类】
Java程序中有了类的定义
然后通过类就可以创建对象
有了对象之后,可以让对象直接协作起来形成一个系统
类—【实例化】---->对象
对象又被称为实例/instance
对象–【抽象】----->类
重点:
类描述的是对象的共同特征。
共同特征例如:身高特征
这个身高特征在访问的时候,必须先创建对象,通过这个对象去访问这个特征。
因为这个特征具体到某个对象上之后,值不同。有的对象身高1.80,有的对象身高2.80.
一个类主要描述什么信息呢?
一个类主要描述的是 状态 + 动作
状态信息:名字、身高、性别、年龄
动作信息:吃、唱歌、跳舞、学习
状态—>一个类的属性
动作—>一个类的方法
类{
属性;//描述对象的状态信息
方法;//描述对象的动作信息
}
注意 :
状态和动作当具体到某个对象上之后,发现最终的结果可能不一样
对象和对象之间有共同特征,但是具体到对象之后有数据的差异。
类的定义【从这这里开始编写代码】
语法结构:
[修饰符列表] class 类名{
属性;
方法;
}
学生类,描述所有学生对象的共同特征:
学生对象有哪些状态信息:
* 学号【int】
* 名字【String】
* 性别【boolean】
* 年龄【int】【年龄是一个属性,年龄是一个数据,是数据就应该有数据类型】
* 住址【String】
…
学生对象有哪些动作信息:
* 吃饭
* 睡觉
* 学习
* 玩
* 唱歌
* 跳舞
…
重点:属性通常是采用一个变量的形式来完成定义的。
int no;
int age;
String name;
String address;
boolean sex;
- java语言中包括两种数据类型:
-
基本数据类型
byte
short
int
long
float
double
boolean
char -
引用数据类型
String.class SUN提供的
System.class SUN提供的Student.class 程序员自定义的
User.class 程序员自定义的
Product.class 程序员自定义的
Customer.class 程序员自定义的
… -
java语言中所有的class都属于引用数据类型。
//学生类
//学生类是一个模板
//描述了所有学生的共同特征【状态+行为/动作】
//当前类只描述学生的状态信息【属性】
//Student是类,是引用数据类型,类型名:Student
public class Student{
//类体=属性+方法
//属性【存储数据采用变量的形式】
//由于变量定义在类体之内,方法体之外,所以这种变量被称为“成员变量”
//所有学生都有学号信息
//但是每一个学生的学号信息是不同的
//所以,要访问这个学号,就必须创建一个对象,通过对象来访问学号这个信息
//学号信息不能通过“类”直接去访问,所以,这种成员变量又被称为“实例变量”
//对象又被称为实例,实例变量又被称为对象变量。【对象级别的变量】
//不创建对象,这个no变量的内存空间是不存在的,只有创建了对象,这个no变量的内存空间才会被创建
int no;
String name;
boolean sex;
int age;
String addr;
}
/*
成员变量未赋值,系统会给默认值
数据类型 默认值
--------------------------------
byte short int long 0
float double 0.0
boolean false
char \u0000
引用数据类型 null空值
*/
对象的创建和使用
public class OOTest01{
public static void main(String[] args){
int i=10;
//int是基本数据类型
//i是变量名
//10是一个int类型的字面值
//通过一个类可以实例化N个对象
//实例化对象的语法: new 类名();
//new是java语言中的一个运算符
//new运算符的作用是创建对象,在JVM中的堆内存开辟新的内存空间
//方法区内存:在类加载的时候,class字节码代码片段被加载到该内存空间中
//栈内存(局部变量):方法代码片段执行时,会给该方法分配内存空间,在栈内存中压栈
//堆内存:new的对象在堆内存中存储
//new Student();
//Student是一个引用数据类型
//s是变量名,
//new Student()是一个学生对象
//s是一个局部变量,【在栈内存中存储】
//什么是对象?new运算符在堆内存中开辟的内存空间就是对象
//什么是引用?引用是一个变量,只不过这个变量中保存的是另一个java对象的内存地址
//对于java语言,程序员不能直接操作堆内存,java中没有指针,不像C语言
//对于java语言,程序员只能通过“引用”来访问堆内存中对象内部里的实例变量
Student s=new Student();
//访问实例变量的语法格式:
//读取: 引用.变量名
//修改: 引用.变量名=值
/*
int stuNo=s.no;
String stuName=s.name;
int stuAge=s.age;
boolean stuSex=s.sex;
String stuAddr=s.addr;
System.out.println("学号 ="+stuNo);
System.out.println("姓名 ="+stuName);
System.out.println("年龄 ="+stuAge);
System.out.println("性别 ="+stuSex);
System.out.println("住址 ="+stuAddr);
输出默认值
学号 =0
姓名 =null
年龄 =0
性别 =false
住址 =null
*/
System.out.println(s.no);
System.out.println(s.name);
System.out.println(s.age);
System.out.println(s.sex);
System.out.println(s.addr);
System.out.println("------------------------------------");
s.no=10;
s.name="jack";
s.age=20;
s.sex=true;
s.addr="北京";
System.out.println(s.no);
System.out.println(s.name);
System.out.println(s.age);
System.out.println(s.sex);
System.out.println(s.addr);
//再次实例一个全新的对象,
//stu是一个引用
//stu同时也是一个局部变量
//Student是变量数据类型
Student stu=new Student();
System.out.println(stu.no);
System.out.println(stu.name);
System.out.println(stu.age);
System.out.println(stu.sex);
System.out.println(stu.addr);
//编译报错,no是实例变量,不能直接采用“类名”的方式访问
//因为no是实例变量,对象级别的变量,变量存储在java对象中,
//只有先有对象,通过对象才能访问no这个实例变量,不能直接通过“类名”来访问
//创建对象-用引用来赋值-访问引用
//System.out.println(Student.no);
}
}
/*
局部变量在栈中存储,
成员变量中的实例变量在堆内存的java对象内部存储
实例变量是一个对象一份,100个对象就有100份
*/
以上程序执行的内存分析图
//家庭住址类
public class Address{
//属性【成员变量之实例变量】
//城市
//String是一种引用数据类型,city是一个变量名,属于实例变量
//city是一个引用:保存内存地址的一个变量,这个变量保存内存地址指向了堆内存当中的对象
String city;
//街道
String street;
//邮编
String zipcode;
}
//用户类
public class User{
//属性【以下都是成员变量之实例变量】
//用户编号
//int是基本数据类型:整数型
//no是一个实例变量
int no;
//用户名
//String是引用数据类型:代表字符串
//name是一个实例变量
//name是一个引用
String name;
//家庭住址
//Address是引用数据类型:代表家庭住址
//addr是一个实例变量
//addr是一个引用
Address addr;
}
//测试类
public class OOTest02{
public static void main(String[] args){
//创建一个User对象
//u是一个局部变量
//u是一个引用
//u是保存内存地址指向堆内存的User对象
User u=new User();
//输出User变量内部实例变量的值
System.out.println(u.no);//0
System.out.println(u.name);//null
System.out.println(u.addr);//null
//对User对象内的实例变量值进行修改
u.no=110;
u.name="jack";//注意:"jack"实际上是一个java对象,是String对象
u.addr=new Address();
//在此注意:addr它是一个Address类型的变量。不是什么字符串之类的。
//只能用创建对象的方式来进而访问它。
//String比较特殊,直接加字符串就行,但是本质上还是在堆内存中创建了一个String对象
//单独对u的addr进行输出。
//addr这个实例变量会创建一个Address对象,详见图。
//在main方法中,我只能看见一个引用“u”。
System.out.println(u.name+"居住的城市是:"+u.addr.city);
System.out.println(u.name+"居住的街道是:"+u.addr.street);
System.out.println(u.name+"邮编:"+u.addr.zipcode);
//改变具体的addr内容。
//只要把整个儿的复制过来修改就行
u.addr.city="北京";
u.addr.street="朝阳";
u.addr.zipcode="111111";
System.out.println("---------------------------------------");
System.out.println(u.name+"居住的城市是:"+u.addr.city);
System.out.println(u.name+"居住的街道是:"+u.addr.street);
System.out.println(u.name+"邮编:"+u.addr.zipcode);
}
}
//引用,它既可以是局部变量,也可以是成员变量。
//引用数据类型后的变量,都能看成引用。
//引用数据类型后都是指向一个对象的内存地址。
//不能直接操作堆内存,只能通过引用,一步一步的进行访问。
//所以,u.addr这个它也是一个引用。u.addr.city
以上程序执行的内存分析图
public class OOTest03{
public static void main(String[] args){
//u是引用
//u是局部变量
User u=new User();
//在OOTest02.java中编写的代码
//u.addr=new Address();
//换一种写法
//a是引用
//a是局部变量
Address a=new Address();
u.addr=a;
System.out.println(u.addr.city);//null
a.city="天津";
System.out.println(u.addr.city);//天津
}
}
画图,一步步按照顺序来,一定可以弄懂原理。
public class OOTest04{
public static void main(String[] args){
//创建一个丈夫对象
Husband huangxiaoming=new Husband();
huangxiaoming.name="黄晓明";
//创建一个妻子对象
Wife baby=new Wife();
baby.name="baby";
//结婚【能通过丈夫找到妻子,同时通过妻子也能找到丈夫】
huangxiaoming.w=baby;
baby.h=huangxiaoming;
//得到以上“黄晓明”的妻子的名字
System.out.println(huangxiaoming.name+"的妻子名字叫:"+baby.name);
//直接把baby的name给访问出来,体现不出来他俩是夫妻关系
System.out.println(huangxiaoming.name+"的妻子名字叫:"+huangxiaoming.w.name);
}
}
//妻子类
public class Wife{
//名字
String name;
//妻子对象中含有丈夫引用
Husband h;
}
//丈夫类
public class Husband{
//名字
String name;
//丈夫对象中含有妻子引用
Wife w;
}
与内存图结合,一步步来,
总之,引用数据存储的都是内存地址,在赋值的时候,都是赋内存地址的。
内存地址指向这个对象,实际上,可以直接在堆内存里进行指向。
空指针异常
//测试程序
public class OOTest05{
public static void main(String[] args){
Customer c=new Customer();
System.out.println(c.id);//0
c=null;
//以下程序编译通过,运行出错
//出现错误:java.lang.NullPointerException
//空指针异常
//出现情况:空引用访问“实例”相关的数据
System.out.println(c.id);
}
}
//“实例”相关的数据表示:这个数据访问的时候必须要有对象的参与。这就是实例相关的数据
//顾客类
public class Customer{
int id;
}
需求:
定义一个计算机类【电脑/笔记本】,计算机类的属性:
*品牌
*型号
*颜色
定义一个学生类,学生类的属性:
*学号
*姓名
*学生有一台笔记本电脑
请编写程序表示以上的类,然后分别将类创建成对象,
对象数量不限,然后让其中一个学生去使用其中一台笔记本电脑
编译并运行,并且将整个的执行过程采用画图方式描述出来
所有的代码写到这里来。
public class OOTest06{
public static void main(String[] args){
Computer computer1=new Computer();
Computer computer2=new Computer();
computer1.brand="asus";
computer1.type='A';
computer1.color="red";
computer2.brand="lenevo";
computer2.type='B';
computer2.color="black";
Student student1=new Student();
student1.no=110;
student1.name="jack";
student1.c=computer1;
System.out.println(student1.no);
System.out.println(student1.name);
System.out.println(student1.c.brand);
System.out.println(student1.c.type);
System.out.println(student1.c.color);
//注意,直接访问student1.c它实际上是一个内存地址的。
//当然,也可以直接student1.c=new Computer();这个学生直接换了一台新的电脑
}
}
class Computer{
String brand;
char type;
String color;
}
class Student{
int no;
String name;
Computer c;
}
//关联关系,通过A对象,能够找到B对象。A中含有B的引用
以上程序执行的内存分析图
关于JVM内存管理
-
JVM(Java虚拟机)主要包括三块内存空间,分别是:栈内存、堆内存、方法区内存。
-
堆内存和方法区内存各有1个,一个线程一个栈内存
-
方法调用的时候,该方法所需要的内存空间在栈内存中分配,称为压栈。方法执行结束之后,该方法所属的内存空间释放,称为弹栈
-
栈中主要存储的是方法体当中的局部变量
-
方法的代码片段以及整个类的代码片段都被存储到方法区内存当中,在类加载的时候这些代码片段会载入
-
在程序执行过程中使用new运算符创建的Java对象,存储在堆内存当中,对象内部有实例变量,所以实例变量存储在堆内存当中
-
变量分类:
局部变量【方法体中声明】
成员变量【方法体外声明】
实例变量【前边修饰符没有static】
静态变量【前边修饰符中有static】 -
静态变量存储在方法区内存当中【先背会】
-
三块内存当中变化最频繁的是栈内存,最先有数据的是方法区内存,垃圾回收器主要针对的是堆内存
-
垃圾回收器【自动垃圾回收机制、GC机制】
什么时候会考虑将某个Java对象的内存回收呢?
当堆内存当中的java对象成为垃圾数据的时候,会被垃圾回收器回收什么时候堆内存中的java对象会变成垃圾呢?
没有更多的引用指向它的时候
这个对象无法被访问,因为访问对象只能通过引用的方式访问
下一篇: 构造方法
更多推荐
所有评论(0)