1.面向对象编程(Object Orienteed Programing)
面向对象和面向过程思想的总结:
面向对象离不开面向过程:
? 宏观上:通过面向对象进行整体设计
? 微观上:执行和处理数据,仍然是面向过程。
1.基本概念
a.类的定义:
? 对于一个类来说,有三种成员:属性 field、方法 method、构造器 constructor。
? eg:学生类:**属性(静态数据):**ID、年龄、姓名;**方法(动态行为):**学习、踢球
b.属性(field成员变量):
? 属性用于定义该类或该类对象包含的数据或者说静态特征。属性作用范围是整个类体。
在定义成员变量时可以对其初始化,如果不对其初始化,Java 使用默认的值对其初始化。
属性定义格式:
? [修饰符] 属性类型 属性名 = [默认值]
数据类型 | 默认值 |
---|
整型 | 0 | 浮点型 | 0.0 | 字符型 | ‘\u0000’ | 布尔型 | false | 所有引用类型 | null |
c.方法
**方法用于定义该类或该类实例的行为特征和功能实现。**方法是类和对象行为特征的抽象。
面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。
[修饰符] 方法返回值类型 方法名(形参列表) {
}
eg:编写简单的学生类
public class SxtStu {
int id;
String sname;
int age;
void study(){
System.out.println("我正在学习!");
}
SxtStu(){
}
}
2.简单内存分析(画内存图可帮助理解代码运行过程)
public class SxtStu {
int id;
String sname;
int age;
void study(){
System.out.println("我正在学习!");
}
SxtStu(){
}
public static void main(String[] args) {
SxtStu s1=new SxtStu();
System.out.println(s1.id);
System.out.println(s1.sname);
s1.id = 1001;
s1.sname = "高淇";
System.out.println(s1.id);
System.out.println(s1.sname);
}
}
字迹潦草,改进中:
与类有关信息放在方法区(方法的代码,常量值,static属性和方法);
main()栈帧在栈中(args:null ,s1:地址);
构造器初始化对象放在堆中,并将其地址赋给栈中的s1.
3.构造方法(构造器 constructor)
构造器用于对象的初始化,而不是创建对象!
构造器 4 个要点:
构造器里使用 return 返回某个值。
- 如果我们没有定义构造器,则编译器会自动定义一个无参的构造方法。如果已定义
则编译器不会自动添加!
public class Point {
double x,y;
Point(double _X,double _y){
x=_X;
y=_y;
}
public double getDistance(Point p){
return Math.sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
}
public static void main(String[] args) {
Point p1=new Point(3.0,4.0);
Point origin=new Point(0.0,0.0);
System.out.println(p1.getDistance(origin));
}
}
4.构造方法的重载
public class user {
int id;
String name;
String pwd;
public user(){
}
public user(int id,String name){
this.id=id;
this.name=name;
System.out.println(id);
System.out.println(name);
System.out.println(this);
}
public user(int id, String name, String pwd) {
System.out.println(id);
System.out.println(name);
System.out.println(this);
}
public static void main(String[] args) {
user u1=new user();
user u2=new user(001,"KZY");
user u3=new user(002,"KKZY","123456");
}
}
如果方法构造中形参名与属性名相同时,需要使用 this 关键字区分属性与形参。
this.id 表示属性 id;id 表示形参 id
5.JAVA虚拟机内存模型概念
Java 虚拟机的内存可以分为三个区域:栈 stack、堆 heap、方法区 method area。
虚拟机栈(简称:栈)的特点如下:
1.栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变
量、操作数、方法出口等)
2.JVM 为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变
量等)
3.栈属于线程私有,不能实现线程间的共享!
4.栈的存储特性是“先进后出,后进先出”
5.栈是由系统自动分配,速度快!栈是一个连续的内存空间!
堆的特点如下:
1.堆用于存储创建好的对象和数组(数组也是对象)
2.JVM 只有一个堆,被所有线程共享
3.堆是一个不连续的内存空间,分配灵活,速度慢!
4.堆被所有的线程所共享,在堆上的区域,会被垃圾回收器做进一步划分,例如新生
代、老年代的划分。
方法区(也是堆)特点如下:
1.方法区是 JAVA 虚拟机规范,可以有不同的实现。
? i. JDK7 以前是“永久代”
? ii. JDK7 部分去除“永久代”,静态变量、字符串常量池都挪到了堆内存中
? iii. JDK8 是“元数据空间”和堆结合起来。
2.JVM 只有一个方法区,被所有线程共享!
3.方法区实际也是堆,只是用于存储类、常量相关的信息!
4.用来存放程序中永远是不变或唯一的内容。(类信息【Class 对象,反射机制中会
重点讲授】、静态变量、字符串常量等)
5.常量池主要存放常量:如文本字符串、final 常量值。
编写 Person 类并分析内存
public class Person {
String name;
int age;
public void show(){
System.out.println(name);
}
public static void main(String[ ] args) {
Person p1 = new Person();
p1.age = 24;
p1.name = "张三";
p1.show();
Person p2 = new Person();
p2.age = 35;
p2.name = "李四";
p2.show();
Person p3 = p1;
Person p4 = p1;
p4.age = 80;
System.out.println(p1.age);
}
}
a.参数传值机制
Java 中,方法中所有参数都是“值传递”,也就是“传递的是值的副本”。 也就是说,
我们得到的是“原参数的复印件,而不是原件”。
· 基本数据类型参数的传值
传递的是值的副本。 副本改变不会影响原件。
· 引用类型参数的传值
传递的是值的副本。但是引用类型指的是“对象的地址”。因此,副本和原参数都指向
了同一个“地址”,改变“副本指向地址对象的值,也意味着原参数指向对象的值也发生了
改变
b.垃圾回收(提前接触,认识即可)
1.垃圾回收原理和算法
Java 的内存管理很大程度就是:堆中对象的管理,其中包括对象空间的分配和释放。
**对象空间的分配:**使用 new 关键字创建对象即可
**对象空间的释放:**将对象赋值 null 即可。
任何一种垃圾回收算法一般要做两件基本事情:
1.发现无用的对象
2.回收无用对象占用的内存空间。
- 引用计数法
堆中的每个对象都对应一个引用计数器,当有引用指向这个对象时,引用计数器加
1,而当指向该对象的引用失效时(引用变为 null),引用计数器减 1,最后如果该对象
的引用计算器的值为 0 时,则 Java 垃圾回收器会认为该对象是无用对象并对其进行回收。
优点是算法简单,缺点是“循环引用的无用对象”无法别识别。
识别。导致无法回收
public class Student {
String name;
Student friend;
public static void main(String[ ] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.friend = s2;
s2.friend = s1;
s1 = null;
s2 = null;
}
}
2.引用可达法(根搜索算法)
程序把所有的引用关系看作一张图,从一个节点 GC ROOT 开始,寻找对应的引用
节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找
完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。
6.this的用法
this 本质就是“当前对象的地址”!
this 的用法:
必须位于构造方法的第一句。
this 的用法详解
public class TestThis {
int a, b, c;
TestThis() {
System.out.println("正要初始化一个Hello对象");
}
TestThis(int a, int b) {
this();
a = a;
this.a = a;
this.b = b;
}
TestThis(int a, int b, int c) {
this(a, b);
this.c = c;
}
void sing() {
}
void eat() {
this.sing();
System.out.println("你妈妈喊你回家吃饭!");
}
public static void main(String[ ] args) {
TestThis hi = new TestThis(2, 3);
hi.eat();
}
}
7.static关键字
静态变量(类变量)、静态方法(类方法):static 声明的属性或方法。
静态变量/静态方法生命周期和类相同,在整个程序执行期间都有效。它有如下特点:
- 为该类的公用变量,属于类,被该类的所有实例共享,在类载入时被初始化。
- static 变量只有一份。
- 一般用“类名.类变量/方法”来调用。
- 在 static 方法中不可直接访问非 static 的成员。
static 关键字的使用
public class TestStatic {
int id;
String name;
String pwd;
static String company="北京尚学堂";
public TestStatic(int id,String name){
this.id=id;
this.name=name;
}
public void login(){
System.out.println(name);
}
public static void printComany(){
System.out.println(company);
}
public static void main(String[] args) {
TestStatic u=new TestStatic(101,"高小七");
TestStatic.printComany();
TestStatic.company="北京阿里爷爷";
TestStatic.printComany();
}
}
输出结果:北京尚学堂
? 北京阿里爷爷
8.静态初始化块
构造方法用于对象的普通属性初始化。
静态初始化块,用于类的初始化操作,初始化静态属性。
在静态初始化块中不能直接访问非 static 成员。
铺垫:静态初始化块执行顺序(学完继承再看这里):
- 上溯到 Object 类,先执行 Object 的静态初始化块,再向下执行子类的静态初始化块,
直到类的静态初始化块为止。
static 静态初始化块
public class TestStatic2 {
static String company;
static{
System.out.println("执行类的初始化工作");
company="北京尚学堂";
printCompany();
}
public static void printCompany(){
System.out.println(company);
}
public static void main(String[] args) {
}
}
输出结果:执行类的初始化工作
? 北京尚学堂
9.变量的分类和作用域
变量有三种类型:局部变量、成员变量(也称为实例变量)和静态变量。
? 局部变量、成员变量、静态变量的核心区别
类型 | 声明位置 | 从属于 | 生命周期(作用域) |
---|
局部变量 | 方法或语句块内部 | 方法/语句块 | 从声明位置开始,到方法或语句块结束 | 成员变量(实例变量) | 类内部,方法外部 | 对象 | 对象创建,成员变量也跟着创建;对象消失,成员变量也跟着消失。 | 静态变量(类变量) | 类内部,static修饰 | 类 | 类被加载,静态变量就有效 |
10.包机制(package、import)
包(package)相当于文件夹对于文件的作用。用于管理类、用于解决类的重名问题。
package 的使用
package com.itkang;
public class Test {
public static void main(String[ ] args) {
System.out.println("helloworld");
}
}
JDK 中的主要包
? 表 JDK 中的主要包
Java 中的常用包 | 说明 |
---|
java.lang | 包含一些 Java 语言的核心类,如 String、Math、Integer、System 和 Thread。 | java.awt | 包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。 | java.net | 包含执行与网络相关的操作的类。 | java.io | 包含能提供多种输入/输出功能的类。 | java.util | 包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。 |
导入类 import
如果要使用其他包的类,需使用 import,从而在本类中直接通过类名来调用,否则就
需要书写类的完整包名和类名。
注意要点:
-
Java 会默认导入 java.lang 包下所有的类,因此这些类我们可以直接使用。 -
如果导入两个同名的类,只能用包名+类名来显示调用相关类: ? java.util.Date date = new java.util.Date()
静态导入的使用
package itkang;
import static java.lang.Math.*;
import static java.lang.Math.PI;
public class Test{
public static void main(String [ ] args){
System.out.println(PI);
System.out.println(random());
}
}
|