Java全栈学习day04(面向对象)

Java全栈学习day04(面向对象),第1张

1、面向过程和面向对象
  • 面向对象和面向过程都是解决问题的思维方式,都是代码组织的方式。
  • 解决简单问题使用面向过程。
  • 解决复杂问题,在宏观上使用面向对象,微观上任然是面向过程。
  • 面向对象三大特性:封装、继承、多态。
  • 面向过程只有一个封装功能。
  • 对象是一种数据结构(对数据的管理模式),将数据和数据行为放到一起。
2、对象和类
  • 类可以看做是一个模版,或者图纸,系统根据类的定义来造出对象。类就是对象的抽象。
  • .对象是具体的事物;类是对对象的抽象;
  • 类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
  • 类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。

简单的学生类:

public class Student{
    //属性(成员变量)
    int id;//学号
    String name;//姓名
    int age;//年龄
    void study(){
        System.out.println("我喜欢学习!");
    }
    //空参构造器,构造方法
    Student(){
        
    }
  
}

一个典型的类

class Computer {
    String brand;  //品牌
}
public class SxtStu {
    //属性 field
    int id;
    String sname;
    int age;
    Computer comp;
    //方法
    void study() {
        System.out.println("我正在学习!使用我们的电脑,"+comp.brand);
    }
    //构造器
    SxtStu() {
    }
    public static void main(String[] args) {
        SxtStu stu1 = new SxtStu();
        stu1.sname = "张三";
        Computer comp1 = new Computer();
        comp1.brand = "联想";
        stu1.comp = comp1;
        stu1.study();
    }
}

对应的UML图

属性(成员变量)的默认值

数据类型默认值
整型0
浮点型0.0
字符型‘\u0000’
布尔型false
所有引用类型null
3、面向对象内存分析

​ Java虚拟机的内存可以分为三个区域:栈(stack)、堆(heap)、方法区(method area)

  1. 栈的特点:

    • 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈。
    • JVM为每一个线程都创建一个栈,用于存放线程执行方法的信息。
    • 栈属于线程私有,不能共享。
    • 特性:先进后出,后进先出。
    • 栈由系统自动分配,连续的内存空间。
  2. 堆的特点:

    • 堆用于存储创建好的对象和数组。
    • JVM只有一个堆,所有线程共享。
    • 堆是不连续的内存空间,分配灵活,速度慢。
  3. 方法区(静态区)的特点:

    • JVM只有一个方法区,所有线程共享。
    • 方法去实际上也是堆,用于存储类、常量相关信息。
    • 用来存放程序中永远不变或者唯一的内容。

4、构造方法
  1. 声明格式

    [修饰符] 类名(形参列表){
        //n条语句
    }
    
  2. 要点

    • 通过new关键字调用。
    • 构造器虽然有返回值,但是不能定义返回值类型,不能在构造器里面使用return返回值。
    • 如果没有定义构造器,则编译器会自动生成一个空参构造器。
    • 构造器方法名和类名一致。
  3. 练习题

    1. 定义一个“点”(Point)类用来表示二维空间中的点(有两个坐标)。要求如下:

    (1) 可以生成具有特定坐标的点对象。

    (2) 提供可以设置坐标的方法。

    (3)提供可以计算该“点”距另外一点距离的方法。

    public class Point{
        double x;
        double y;
        //构造器
        public Point(double x,double y){
            this.x=x1;
            this.y=y1;
        }
        //两点距离方法
        public double getDistance(Point p){
            return Math.sqrt(x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
        }
    }
    public class Test{
        public static void main(String[] args){
            Point p=new Point(3.0,4.0);
            Point o=new Point(0.0,0.0);
            System.out.println(p.getDistance(o));
        }
    }
    
5、垃圾回收机制
  1. 内存管理

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

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

    • 对象空间的释放:将对象赋值null即可。垃圾回收器将负责回收所有”不可达”对象的内存空间。

  2. 垃圾回收过程

    1. 发现无用对象。
    2. 回收无用对象占用的内存空间。
  3. 垃圾回收相关算法

    1. 引用计数法

      堆中每个对象都有一个引用计数。被引用一次,计数加1. 被引用变量值变为null,则计数减1,直到计数为0,则表示变成无用对象。优点是算法简单,缺点是“循环引用的无用对象”无法别识别。

    2. 引用可达法(根搜索算法)

      程序把所有的引用关系看作一张图,从一个节点GC ROOT开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。

  4. 堆内存划分

对象分为三种状态:

  1. 年轻代:新生对象放在Eden区。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象,对应的是Minor GC,每次 Minor GC 会清理年轻代的内存,算法采用效率较高的复制算法,频繁的 *** 作,但是会浪费内存空间。当“年轻代”区域存放满对象后,就将对象存放到年老代区域。
  2. 年老代:在年轻代中经历了N(默认15)次垃圾回收后仍然存活的对象,就会被放到年老代中。用来存放生命周期较长的对象。年老代对象越来越多,我们就需要启动Major GC和Full GC(全量回收),来一次大扫除,全面清理年轻代区域和年老代区域。
  3. 持久代:用于存放静态文件,如Java类、方法等。持久代对垃圾回收没有显著影响。
  1. Minor GC:用于清理年轻代区域。
  2. Major GC:用于清理老年代区域。
  3. Full GC:用于清理年轻代、年老代区域。
  1. 垃圾回收过程

1、新创建的对象,绝大多数都会存储在Eden中,

2、当Eden满了(达到一定比例)不能创建新对象,则触发垃圾回收(GC),将无用对象清理掉,

​ 然后剩余对象复制到某个Survivor中,如S1,同时清空Eden区

3、当Eden区再次满了,会将S1中的不能清空的对象存到另外一个Survivor中,如S2,

​ 同时将Eden区中的不能清空的对象,也复制到S1中,保证Eden和S1,均被清空。

4、重复多次(默认15次)Survivor中没有被清理的对象,则会复制到老年代Old(Tenured)区中,

5、当Old区满了,则会触发一个一次完整地垃圾回收(FullGC),之前新生代的垃圾回收称为(minorGC)

  1. JVM调优(Full GC原因)

    1.年老代(Tenured)被写满

    2.持久代(Perm)被写满

    3.System.gc()被显式调用(程序建议GC启动,不是调用GC)

    4.上一次GC之后Heap的各域分配策略动态变化

  2. 开发过程中容易造成的内存泄漏的 *** 作

    1. 创建大量无用对象

    我们在需要大量拼接字符串时,使用了String而不是StringBuilder。

    1. 静态集合类的使用

    像HashMap、Vector、List等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放。

    1. 各种连接对象(IO流对象、数据库连接对象、网络连接对象)未关闭

    IO流对象、数据库连接对象、网络连接对象等连接对象属于物理连接,和硬盘或者网络连接,不使用的时候一定要关闭。

    1. 监听器的使用

    释放对象时,没有删除相应的监听器。

    要点:

    1. 程序员无权调用垃圾回收器。

    2. 程序员可以调用System.gc(),该方法只是通知JVM,并不是运行垃圾回收器。尽量少用,会申请启动Full GC,成本高,影响系统性能。

    3. finalize方法,是Java提供给程序员用来释放对象或资源的方法,但是尽量少用。

6、this关键字
  1. 创建对象的过程

    • 分配对象空间,并将对象成员变量初始化为0或为空。
    • 执行属性值的显示初始化。
    • 执行构造方法。
    • 返回对象的地址给相关的变量。

** this**:本质上就是用来指代当前对象。

  1. this最常用的用法

    • 普通方法中,this指向调用该方法的对象;构造方法中,this指向正要初始化的对象。
    • 使用this关键字调用重载的构造方法,必须位于构造方法的第一句。
    • this不能用于static方法中。
7、static关键字

​ 用static声明的成员变量为静态成员变量,也称为类变量。 类变量的生命周期和类相同,在整个应用程序执行期间都有效。

  1. 特点

    1. 为该类的公用变量,属于类,被该类的所有实例共享,在类被加载时被显式初始化。
    2. 对于该类的对象来说,static成员变量只有一份。被该类的所有对象共享。
    3. 一般使用类名.类属性/方法来调用。
    4. 在static方法中不可以直接访问非static的成员。
  2. 核心要点

    1. static 修饰的成员变量和方法从属于类。
    2. 普通变量和方法从属于对象。
8、静态初始化块

静态初始化块执行顺序

  • 上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到我们的类的静态初始化块为止。
  • 构造方法执行顺序和上面顺序一样!!
9、参数传值机制
  1. 基本数据类型参数的传值

    传递的是值的副本,不会影响原来的参数。

  2. 引用数据类型参数的传值

    引用类型指的是”对象的地址“。因此在传值的时候副本和原参数都指向同一个地址,改变副本指向的地址值会影响原参数的值。

10、包

​ 包机制是Java中管理类的重要手段。 开发中,我们会遇到大量同名的类,通过包我们很容易对解决类重名的问题,也可以实现对类的有效管理。 包对于类,相当于文件夹对于文件的作用。

11、package
  1. 使用package两个要点:

    • 通常是类的第一句非注释性语句。
    • 包名:域名倒着写,再加上模块名,便于内部管理类。
  2. 注意事项

    • 写项目都要加包,不要使用默认包。
    • com.gao和com.gao.car,这两个包没有包含关系,是两个完全独立的包。只是在逻辑上前者是后者的一部分。
  3. JDK主要包

    Java中常用的包说明
    java.lang包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。
    java.awt包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。
    java.net包含执行与网络相关的 *** 作的类。
    java.io包含能提供多种输入/输出功能的类。
    java.util包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。

    注意:

    1. Java会默认导入java.lang包下所有的类,因此这些类我们可以直接使用。

    2. 如果导入两个同名的类,只能用包名+类名来显示调用相关类:

  4. 静态导入

静态导入(static import)是在JDK1.5新增加的功能,其作用是用于导入指定类的静态属性,这样我们可以直接使用静态属性。

package cn.sxt;
 //以下两种静态导入的方式二选一即可
import static java.lang.Math.*;//导入Math类的所有静态属性
import static java.lang.Math.PI;//导入Math类的PI属性
 
public class Test2{
    public static void main(String [] args){
        System.out.println(PI);
        System.out.println(random());
    }
}
12、练习题

一、选择题

1.以下语句中关于Java构造方法的说法错误的是(B )。(选择一项)

A.构造方法的作用是为创建对象进行初始化工作,比如给成员变量赋值

B.一个Java类可以没有构造方法,也可以提供1个或多个构造方法

C.构造方法与类同名,不能书写返回值类型

D.构造方法的第一条语句如果是super(),则可以省略,该语句作用是调用父类无参数的构造方法

2.在Java中,以下程序编译运行后的输出结果为(D )。(选择一项)

public class Test {
    int x, y;
    Test(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public static void main(String[] args) {
        Test pt1, pt2;
        pt1 = new Test(3, 3);
        pt2 = new Test(4, 4);
        System.out.print(pt1.x + pt2.x);
    }
}

A.6

B.34

C.8

D.7

3.在Java中关于静态方法,以下说法中正确的是( AC)。(选择二项)

A.静态方法中不能直接调用非静态方法

B.非静态方法中不能直接调用静态方法

C.静态方法可以用类名直接调用

D.静态方法里可以使用this

4.下列选项中关于Java中类方法的说法错误的是( AC)。(选择二项)

A.在类方法中可用this来调用本类的类方法

B.在类方法中调用本类的类方法时可直接调用

C.在类方法中只能调用本类中的类方法

D.在类方法中调用实例方法需要先创建对象

5.分析如下Java程序的代码所示,则编译运行后的输出结果是(C )。(选择一项)

public class Test {
    int count=9;
    public void count1(){
        count=10;
        System.out.print("count1="+count);
    }
    public void count2(){
        System.out.print("count2="+count);
    }
    public static void main(String[ ] args) {
        Test t=new Test();
        t.count1();
        t.count2();
    }
}
 A.count1=9; count2=9;

 B.count1=10;count2=9;

 C.count1=10; count2=10;

 D.count1=9; count2=10;

二、简答题
  1. 面向过程和面向对象的区别。
答:面向过程是解决问题的步骤;面向对象是吧问题分解成对象进行解决。
  2. 类和对象的关系
答:类是对对象的抽象;对象是具体事物。
  3. 构造方法的作用和特征
答:作用:用于对象初始化。
特征:
1、用new关键字调用;
2、返回值类型为本类,不能用return返回某个值;
3、没有定义构造器时会自动分配空参构造器;
4、构造器名称与类名一致。
  4. this关键字的作用和用法
作用:创建好的对象的地址。
用法:
1、普通方法中,this指向调用该方法的对象;构造方法中,this指向正要初始化的对象。
2、使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
3、this不能用于static方法中。
  5. 简述static关键字的作用。
(1). 为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。
(2). 对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享!!
(3). 一般用“类名.类属性/方法”来调用。(也可以通过对象引用或类名(不需要实例化)访问静态成员。)
(4). 在static方法中不可直接访问非static的成员。
三、编码题

1. 编写 Java 程序用于显示人的姓名和年龄。定义一个人类Person。 该类中应该有两个私有属性: 姓名 (name) 和年龄 (age) 。定义构造方法用来初始化数据成员。再定义显示(display()) 方法将姓名和年龄打印出来。在 main 方法中创建人类的实例然后将信息显示。

public class Person {
	private String name;
	private int age;
	public Person(String name,int age) {
		// TODO Auto-generated constructor stub
		this.name=name;
		this.age=age;
	}
	
	void display(Person p) {
		System.out.printf("name=%s,age=%d",this.name, this.age);
	}
	public static void main(String[] args) {
		Person p=new Person("张三",19);
		p.display(p);
	}

}

2. 定义一个圆类——Circle,在类的内部提供一个属性:半径®,同时 提供 两个 方 法 : 计算 面积 ( getArea() ) 和 计算 周长(getPerimeter()) 。 通过两个方法计算圆的周长和面积并且对计算结果进行输出。最后定义一个测试类对 Circle 类进行使用。

import java.util.Scanner;

public class Circle {
	double r;
	Circle(){}
	double getArea() {
		double area=Math.PI*r*r;
		return area;
	}
	double getPerimeter() {
		double perimeter=Math.PI*r*2;
		return perimeter;
	}

}
//---------------------
import java.util.Scanner;

class Test10 {

	public static void main(String[] args) {
		Circle c=new Circle();
		Scanner sc=new Scanner(System.in);
		System.out.println("请输入圆的半径:");
		c.r=sc.nextDouble();
		double area=c.getArea();
		double perimeter=c.getPerimeter();
		System.out.println("圆的面积为:"+area);
		System.out.println("圆的周长为:"+perimeter);
	}
}

3. 构造方法与重载:定义一个网络用户类,信息有用户 ID、用户密码、 email 地址。在建立类的实例时把以上三个信息都作为构造函数的参数输入, 其中用户 ID 和用户密码时必须缺省时 email地址是用户 ID 加上字符串"@gameschool.com"。

public class WebUser {
	private int id;
	private String pwd;
	private String email;
	public WebUser(int id, String pwd, String email) {
		super();
		this.id = id;
		this.pwd = pwd;
		this.email = email;
	}
	public WebUser(int id, String pwd) {
		super();
		this.id = id;
		this.pwd = pwd;
		email=this.id+"@gameschool.com";
	}
	@Override
	public String toString() {
		return "WebUser [id=" + id + ", pwd=" + pwd + ", email=" + email + "]";
	}
	

}
//---------------------------
public class TestWU {
	public static void main(String[] args) {
		WebUser wu=new WebUser(101,"123");
		WebUser wu1=new WebUser(102,"123456","326262222@qq.com");
		System.out.println(wu.toString());
		System.out.println(wu1.toString());
	}

}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/874129.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-13
下一篇2022-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存