java笔记3

1.面向对象编程(Object Orienteed Programing)

面向对象和面向过程思想的总结:

  • 都是解决问题的思维方式,都是代码组织的方式。

  • 面向过程是一种“执行者思维”,解决简单问题可以使用面向过程。

  • 面向对象是一种“设计者思维”,解决复杂、需要协作的问题可以使用面向对象。

面向对象离不开面向过程:

​ 宏观上:通过面向对象进行整体设计

​ 微观上:执行和处理数据,仍然是面向过程。

1.基本概念

a.类的定义:

​ 对于一个类来说,有三种成员:属性 field、方法 method、构造器 constructor

​ eg:学生类:**属性(静态数据):**ID、年龄、姓名;**方法(动态行为):**学习、踢球

b.属性(field成员变量):

属性用于定义该类或该类对象包含的数据或者说静态特征。属性作用范围是整个类体。

在定义成员变量时可以对其初始化,如果不对其初始化,Java 使用默认的值对其初始化

属性定义格式:

​ [修饰符] 属性类型 属性名 = [默认值]

成员变量的默认值
数据类型默认值
整型0
浮点型0.0
字符型‘\u0000’
布尔型false
所有引用类型null

c.方法

**方法用于定义该类或该类实例的行为特征和功能实现。**方法是类和对象行为特征的抽象。

面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。

[修饰符] 方法返回值类型 方法名(形参列表) {
	// n 条语句
}

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 个要点:

  • 构造器通过 new 关键字调用!!

  • 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在

构造器里使用 return 返回某个值。

  • 如果我们没有定义构造器,则编译器会自动定义一个无参的构造方法。如果已定义

则编译器不会自动添加!

  • 构造器的方法名必须和类名一致!
/**
 * 定义一个“点”(Point)类用来表示二维空间中的点(有两个坐标)。要求如下:
 * 1.可以生成具有特定坐标的点对象。
 * 2.提供可以计算该“点”距另外一点距离的方法。
 */
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) {
		// 创建p1对象
		Person p1 = new Person();
		p1.age = 24;
		p1.name = "张三";
		p1.show();
		// 创建p2对象
		Person p2 = new Person();
        p2.age = 35;
        p2.name = "李四";
        p2.show();
        Person p3 = p1;
        Person p4 = p1;
        p4.age = 80; //对象的值发生改变,所有指向该地址的.age都改变
        System.out.println(p1.age); //   p1.age=p3.age=p4.age=80  p1,p3,p4指向同一地址
	} 
}

a.参数传值机制

Java 中,方法中所有参数都是“值传递”,也就是“传递的是值的副本”。 也就是说,

我们得到的是“原参数的复印件,而不是原件”。

· 基本数据类型参数的传值

传递的是值的副本。 副本改变不会影响原件。

· 引用类型参数的传值

传递的是值的副本。但是引用类型指的是“对象的地址”。因此,副本和原参数都指向

了同一个“地址”,改变“副本指向地址对象的值,也意味着原参数指向对象的值也发生了

改变

b.垃圾回收(提前接触,认识即可)

1.垃圾回收原理和算法
  • 内存管理

Java 的内存管理很大程度就是:堆中对象的管理,其中包括对象空间的分配和释放。

**对象空间的分配:**使用 new 关键字创建对象即可

**对象空间的释放:**将对象赋值 null 即可。

  • 垃圾回收过程

任何一种垃圾回收算法一般要做两件基本事情:

1.发现无用的对象

2.回收无用对象占用的内存空间。

  • 垃圾回收相关算法
  1. 引用计数法

堆中的每个对象都对应一个引用计数器,当有引用指向这个对象时,引用计数器加

1,而当指向该对象的引用失效时(引用变为 null),引用计数器减 1,最后如果该对象

的引用计算器的值为 0 时,则 Java 垃圾回收器会认为该对象是无用对象并对其进行回收。

优点是算法简单,缺点是“循环引用的无用对象”无法别识别。

  • 代码中,s1 和 s2 互相引用对方,导致他们引用计数不为 0,但是实际已经无用,但无法被

识别。导致无法回收

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 总是指向调用该方法的对象。

  • 构造方法中,this 总是指向正要初始化的对象。

  • this()调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且

必须位于构造方法的第一句。

  • this 不能用于 static 方法中。

  • this 是作为普通方法的“隐式参数”,由系统传入到方法中。

this 的用法详解

public class TestThis {

    int a, b, c;

    TestThis() {

    	System.out.println("正要初始化一个Hello对象");

    }

    TestThis(int a, int b) {

    	// TestThis(); //这样是无法调用构造方法的!

   		this(); // 调用无参的构造方法,并且必须位于第一行!

    	a = a;// 这里都是指的局部变量而不是成员变量

    	// 这样就区分了成员变量和局部变量. 这种情况占了this使用情况大多数!

    	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(); // 调用本类中的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;     //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(){
        //login();  //调用非静态成员,编译就会出错
        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.*;//导入Math类的所有静态属性
import static java.lang.Math.PI;//导入Math类的PI属性
public class Test{
    public static void main(String [ ] args){
        System.out.println(PI);
        System.out.println(random());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值