第6章 面向对象基础2020-02-22

Java类的定义规则和使用;

//[类修饰符] class 类名{ 类的成员

public class Demo {

    public int a;//成员变量(属性)

    public void show(){  //成员方法(方法)

    }

    class Inner{    ///嵌套类(了解即可)

    }

    {

        System.out.println();    //代码块(了解即可)

    }

}

编码规范:

类名单词首字母大写

属性和方法第一个单词小写,其他单词首字母大写


属性和局部变量对比



课堂演示


根据需求编写类:

西游记游戏软件中的游戏人物包括:

孙悟空:孙悟空的武器是金箍棒,战斗力五颗星,耐力五颗星

唐  僧:唐僧没有武器,战斗力为零,耐力五颗星

猪八戒:猪八戒的武器是耙子,战斗力四颗星,耐力两颗星

沙  僧:沙僧的武器是月牙铲 ,战斗力三颗星,耐力四颗星


package com.neusoft.test2;

public class Player {

private String name;

private String weapon;

private  String atk="";

private String endurance="";

public void setWeapon(String weapon) {

this.weapon=weapon;

}

public String getWeapon() {

return this.weapon;

}

// 输入数字 确定攻击力几星

public void setAtk(int n) {

for(int i=0;i

atk+="*";

}

}

public void setEndurance(int n) {

for(int i=0;i

this.endurance+="*";

}

}

//获得值

public String getName() {

return name;

}

//赋值

public void setName(String name) {

this.name = name;

}

public void say() {

System.out.println(name+"的武器是"+weapon+"战斗力:"+atk+",耐力:"+endurance);

}

}

测试类

package com.neusoft.test2;

public class test3 {

public static void main(String[] args) {

// TODO Auto-generated method stub

method2();

}

// 初始化人物

public static void method2() {

Player tangseng=  new Player();

tangseng.setName("唐僧");

tangseng.setWeapon("无");

tangseng.setAtk(0);

tangseng.setEndurance(5);;

Player sunwukong=  new Player();

sunwukong.setName("孙悟空");

sunwukong.setWeapon("金箍棒");

// sunwukong.atk="*****";

sunwukong.setAtk(5);

sunwukong.setEndurance(5);

Player zhubajie=  new Player();

zhubajie.setName("猪八戒");

zhubajie.setWeapon("耙子");

zhubajie.setAtk(4);

zhubajie.setEndurance(2);

Player shaseng=  new Player();

shaseng.setName("沙僧");

shaseng.setWeapon("月牙铲");

shaseng.setAtk(3);

shaseng.setEndurance(4);

tangseng.say();

sunwukong.say();

zhubajie.say();

shaseng.say();

}

}

认识对象

类和对象的关系

类是创建对象的模板,对象是类的实例。


对象的创建


对象的使用


课堂练习

编写一个商品的类,要求包含商品名称和商品价格,并且编写一个方法能够在控制台输出“商品名:价格”。并在主函数中调用。

输出示例:

可乐:2.5

鼠标:50

private String name;

private double price;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public double getPrice() {

return price;

}

public void setPrice(double price) {

this.price = price;

}

public void printinfo() {

System.out.println(name+":"+price);

}

}

测试类

package com.neusoft.Test3;

public class test2 {

public static void main(String[] args) {

// TODO Auto-generated method stub

//测试类

method1();

}

public static void method1() {

// 输出示例:

// 可乐:2.5

// 鼠标:50

test1 cola =new test1();

cola.setName("可乐");

cola.setPrice(2.5);

test1 mouse =new test1();

mouse.setName("鼠标");

mouse.setPrice(50);

cola.printinfo();

mouse.printinfo();

}

}

创建对象原理


对象的创建


对象的创建和使用


创建多个对象


创建匿名对象


垃圾回收机制



Finalize()

注意:如果你熟悉C++,那你知道C++允许你为一个类定义一个撤消函数(destructor ),它在对象正好出作用域之前被调用。Java不支持这个想法也不提供撤消函数。finalize() 方法只和撤消函数的功能接近。当你对Java 有丰富经验时,你将看到因为Java使用垃圾回收子系统,几乎没有必要使用撤消函数。

finalize的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存.所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作.

finalize()在什么时候被调用?有三种情况1.所有对象被Garbage Collection时自动调用,比如运行System.gc()的时候.2.程序退出时为每个对象调用一次finalize方法。3.显式的调用finalize方法

除此以外,正常情况下,当某个对象被系统收集为无用信息的时候,finalize()将被自动调用,但是jvm不保证finalize()一定被调用,也就是说,finalize()的调用是不确定的,这也就是为什么sun不提倡使用finalize()的原因



练习

程序段1:

1.fobj = new Object ( ) ;

2.fobj. Method ( ) ;

3.fobj = new Object ( ) ;

4.fobj. Method ( ) ;

问:这段代码中,第几行的fobj 符合垃圾收集器的收集标准?

答:第3行。因为第3行的fobj被赋了新值,产生了一个新的对象,即换了一块新的内存空间,也相当于为第1行中的fobj赋了null值。这种类型的题在认证0考试中是最简单的。

程序段2:

1.Object sobj = new Object ( ) ;

2.Object sobj = null ;

3.sobj = new Object ( ) ;

4.sobj = new Object ( ) ;

问:这段代码中,第几行的内存空间符合垃圾收集器的收集标准?

答:第2行和第4行。因为第2行为sobj赋值为null,所以在此第1行的sobj符合垃圾收集器的收集标准。而第4行相当于为sobj赋值为null,所以在此第3行的sobj也符合垃圾收集器的收集标准。

如果有一个对象的句柄a,且你把a作为某个构造器的参数,即 new Constructor ( a )的时候,即使你给a赋值为null,a也不符合垃圾收集器的收集标准。直到由上面构造器构造的新对象被赋空值时,a才可以被垃圾收集器收集。

程序段3:

1.Object aobj = new Object ( ) ;

2.Object bobj = new Object ( ) ;

3.Object cobj = new Object ( ) ;

4.aobj = bobj;

5.aobj = cobj;

6.cobj = null;

7.aobj = null;

问:这段代码中,第几行的内存空间符合垃圾收集器的收集标准?

答:第4,7行。注意这类题型是认证考试中可能遇到的最难题型了。

行1-3分别创建了Object类的三个对象:aobj,bobj,cobj

行4:此时对象aobj的句柄指向bobj,原来aojb指向的对象已经没有任何引用或变量指向,这时,就符合回收标准。

行5:此时对象aobj的句柄指向cobj,所以该行的执行不能使aobj符合垃圾收集器的收集标准。

行6:此时仍没有任何一个对象符合垃圾收集器的收集标准。

行7:对象cobj符合了垃圾收集器的收集标准,因为cobj的句柄指向单一的地址空间。在第6行的时候,cobj已经被赋值为null,但由cobj同时还指向了aobj(第5行),所以此时cobj并不符合垃圾收集器的收集标准。而在第7行,aobj所指向的地址空间也被赋予了空值null,这就说明了,由cobj所指向的地址空间已经被完全地赋予了空值。所以此时cobj最终符合了垃圾收集器的收集标准。 但对于aobj和bobj,仍然无法判断其是否符合收集标准。

总之,在Java语言中,判断一块内存空间是否符合垃圾收集器收集标准的标准只有两个:

1.给对象赋予了空值null,以下再没有调用过。

2.给对象赋予了新值,既重新分配了内存空间。

最后再次提醒一下,一块内存空间符合了垃圾收集器的收集标准,并不意味着这块内存空间就一定会被垃圾收集器收集。

********对象的使用

构造方法


构造方法的使用


构造方法重载


构造方法调用



构造方法使用


课堂练习


*********实例

package com.neusoft.Test5;

//类名:首字母大写

public class Person {

public  String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

// 构造方法名 与类名相同

// 没有返回值类型 不能void

// 只能在创建对象new 时,调用一次

// 构造方法与对象的初始化相关:1.创建对象时内存分配空间等等准备

// 2.使用构造器可以给成员变量赋值(属性注入)

//默认空参构造问题

    // 1.创建一个类 默认有一个空参构造

// 2 如果手写了一个有参构造器 这个空参构造器就没有了

// 3 如果手写了一个有参构造器 ,需要手写一个空参构造器,才能调用空参构造器

//构造器之间调用问题:1使用this(参数) 2只能放在构造方法的第一行

//一个构造方法只能调用一个方法

public Person() {

this(1);

System.out.println("构造方法person");

}

// 构造方法的重载:参数个数,参数类型不同

public Person(int a) {

System.out.println("构造方法person int a:" + a);

}

public Person(String a) {

System.out.println("构造方法person String a:" + a);

this.name=a;

}

// 普通方法

// 随便起名建议驼峰命名法 :person personAnimal

// 有返回值类型

// 可以使用引用多次调用

public void Person() {

System.out.println("普通方法 person");

Person(90);

}

// 方法的重载 :同一个类方法名相同 ,参数个数,参数类型不同

public void Person(int a) {

System.out.println("普通方法 person int a:" + a);

}

public void Person(String a) {

System.out.println("普通方法 person String a:" + a);

}

}

---------------------------------------------------------------

package com.neusoft.Test5;

public class Test1 {

public static void main(String[] args) {

// TODO Auto-generated method stub

// Person p=new Person("tom");

// System.out.println(p.getName());

//

Person p1=new Person();

p1.Person();

p1.setName("jetty");

System.out.println(p1.getName());

// p.Person();

// p.Person(1);

// p.Person("1");

// p.Person("tom");

//

}

}

静态方法

示例

package com.neusoft.test3;

public class Test {

public static void main(String[] args) {

Test.Statica=100;

Test t1=new Test();

Test t2=new Test();

t1.Objecta=10;

t1.Statica=1000;

t2.Objecta=20;

System.out.println("t1.Objecta:"+t1.Objecta);

System.out.println("t2.Objecta:"+t2.Objecta);

System.out.println("t2.Statica:"+t2.Statica);

}

public int Objecta;

static public int Statica;

}

答案

t1.Objecta:10

t2.Objecta:20

t2.Statica:1000

Java包的概念

使用包注意问题:

在java中位于包中的类,在文件系统中的存放位置,

  必须有与包名层次相对应的目录结构

package语句作为java源文件的第一条语句

每个源文件只能声明一个包

如果没有package语句,则默认为无名包

Java类库中常用的包

java.lang

Java默认包,任何程序中,该包都被自动导入。

位于同一包中的类可以直接访问并使用

访问不同包中的类

使用import关键字引入其它包中的类

必须在package声明后面,类声明前面

import语句可以出现多次

优先级顺序!

行内指定包>引用其他包的具体的类>本包中的类> 引用其他包通配符

//优先级級順序

//第一 优先级最高  import com.neusoft.Test2.Person();手動引入包

//第二    com.neusoft.Test1.Person()当前本包内的类

//第三    import com.neusoft.Test2.*; 使用通配符

代码封装



示例

package com.neusoft.test1;

public class Score {

String star="";

// 展现评分对应的星数

public void printresult() {

System.out.println("感谢您的评价,您对客服的评价结果为:"+star);

}

// 输入对客服的评分  1~5

public void setScore(int score) {

for(int i=0;i

star+="*";

}

}

}

测试类

public class Test1 {

public static void main(String[] args) {

// TODO Auto-generated method stub

method4();

}

public static void method4() {

Scanner sc=new Scanner(System.in);

System.out.println("请对客服打分输入1~5分:");

int score=sc.nextInt();

Score s=new Score();

s.setScore(score);

s.star="*********";

s.printresult();

}

静态:static关键字



示例

package com.neusoft.test3;

public class Person {

static String country="China";

String name="tom";

static public void say() {

System.out.println(country);

// System.out.println(name);// 静态方法内部只能调用静态方法及静态属性

//                           不能调用成员方法,成员变量

}

----------

测试类

package com.neusoft.test3;

public class Test1 {

public static void main(String[] args) {

// TODO Auto-generated method stub

// System.out.println(Person.country);

Person.say(); 静态方法可直接写

// System.out.println(new Person().name);

}

}


成员方法与静态方法区分

package com.neusoft.test3;

public class People {

public static void main(String[] args) {

new People().method1();

method2();

}

public  void method1() {

System.out.println("成员方法");//需要创建对象后引用new People().method1(); 与对象有关

}

public static void method2() {

System.out.println("静态方法");//被static修用饰 可直接 用method2(); 与类有关

}

}



示例

package com.neusoft.test3;

public class Test {

  //静态代码块

static {

System.out.println("静态代码块在类初始化时只调用一次");

}

//代码块 (类以内方法外)对象初始化

{

System.out.println("代码块");

}

// 原理(实际) 执行顺序 :静态代码块---》构造器---》代码块

// 执行结果 顺序 : 静态代码块 ---》代码块---》构造器

// 构造器 --》对象初始化

public Test() {

System.out.println("创建对象是 初始化");

}

public static void main(String[] args) {

Test.Statica=100;

Test t1=new Test();

Test t2=new Test();

t1.Objecta=10;

t1.Statica=1000;

t2.Objecta=20;

System.out.println("t1.Objecta:"+t1.Objecta);

System.out.println("t2.Objecta:"+t2.Objecta);

System.out.println("t2.Statica:"+t2.Statica);

}

public int Objecta;

static public int Statica;

}


单例模式



package com.neusoft.test5;

// 懒加载(懒汉式) 单例模式 

public class SingletonA {

static SingletonA a=null;

//单例模式

// 1 .可以创建多个对象,因为可以 new 类名()----》将构造方法私有化private

private SingletonA() {

}

// 2. 当构造器私有化后,一个对象都不能创建

//   类的外部不能调用 构造器--------》在类的内部写一个public static

// 方法,返回创建的对象

public static SingletonA getInstance() {

// 3.创建多个对象了,----》getInstance 加上判断逻辑

if(a==null) {

a=new SingletonA();

}else {

}

return a;

}

}

------------------------

测试

package com.neusoft.test5;

public class Test1 {

public static void main(String[] args) {

// TODO Auto-generated method stub

SingletonA sa1=SingletonA.getInstance();

SingletonA sa2=SingletonA.getInstance();

System.out.println(sa1);

System.out.println(sa2);

}

}



-------------------
package com.neusoft.test5;

//积极加载式  (饿汉式)  单例模式 

public class SingletonB {

// 3.创建对象时机在 static属性中 -----》在类初始化时,执行一次

static SingletonB a=new SingletonB();

//单例模式

// 1 .可以创建多个对象,因为可以 new 类名()----》将构造方法私有化private

private SingletonB() {

}

// 2. 当构造器私有化后,一个对象都不能创建

//   类的外部不能调用 构造器--------》在类的内部写一个public static

// 方法,返回创建的对象

public static SingletonB getInstance() {

return a;

}

}


1、定义一个点类Point,包含2个成员变量x、y分别表示x和y坐标,2个构造器Point()和Point(int x0,y0),以及一个movePoint(int dx,int dy)方法实现点的位置移动,创建两个Point对象p1、p2,分别调用movePoint方法后,打印p1和p2的坐标。[必做题]

2、定义一个矩形类Rectangle: [必做题]

2.1  定义三个方法:getArea()求面积、getPer()求周长,showAll()分别在控制台输出长、宽、面积、周长。

2.2  有2个属性:长length、宽width

2.3  通过构造方法Rectangle(int width, int length),分别给两个属性赋值

2.4  创建一个Rectangle对象,并输出相关信息

3、定义一个笔记本类,该类有颜色(char)和cpu型号(int)两个属性。 [必做题]

3.1 无参和有参的两个构造方法;有参构造方法可以在创建对象的同时为每个属性赋值;

3.2  输出笔记本信息的方法

3.3  然后编写一个测试类,测试笔记本类的各个方法。

4、定义两个类,描述如下: [必做题]

4.1定义一个人类Person:

4.1.1定义一个方法sayHello(),可以向对方发出问候语“hello,my name is XXX”

4.1.2有三个属性:名字、身高、体重

4.2定义一个PersonCreate类:

4.2.1创建两个对象,分别是zhangsan,33岁,1.73;lishi,44,1.74

4.2.2分别调用对象的sayHello()方法。

1、设计一个类Student,该类包括姓名、学号和成绩。设计一个方法,按照成绩从高到低的顺序输出姓名、学号和成绩信息。[选做题]

2、定义一个汽车类Vehicle,要求如下:[选做题]

2.1属性包括:汽车品牌brand(String类型)、颜色color(String类型)和速度speed(double类型),并且所有属性为私有。

2.2至少提供一个有参的构造方法(要求品牌和颜色可以初始化为任意值,但速度的初始值必须为0)。

2.3为私有属性提供访问器方法。注意:汽车品牌一旦初始化之后不能修改。

2.4定义一个一般方法run(),用打印语句描述汽车奔跑的功能

2.5定义测试类VehicleTest,在其main方法中创建一个品牌为“benz”、颜色为“black”的汽车。

你可能感兴趣的:(第6章 面向对象基础2020-02-22)