java08 面向对象(构造方法,对象内存图,对象清除与垃圾回收)

一.设计对象并使用
1.类和对象

        类:是对象共同特征的描述,抽象的     对象:是真实存在的具体的东西,具体的    比如:学生和小明     在Java中必须先设计类,才能获得对象

        定义类:public class 类名 {1.成员变量(属性)2.成员方法(行为)3.构造器 4.代码块 5.内部类}

完整的格式: [public] [abstract] [final] class ClassName [extends SuperName] [implements InterfaceNameList]

类的成员:成员变量和成员方法,构造方法不是类的方法,所以不称为类的成员;类的成员变量可以是基本类型的数据或者数组,也可以是一个类的实例

        对象:类名 对象名 = new 类名();   访问对象的属性:对象名.成员变量  访问行为:对象名.方法名()

    public class phone{
       //属性
        String brand;
        double price;
        //方法
        public void call(){
            System.out.println("打电话");
        }
        public void playgame(){
            System.out.println("玩游戏");
        }
    }
public class phonetest {
    public static void main(String[] args){
        //创建手机对象
        phone p = new phone();
        //给手机赋值
        p.brand = "小米";
        p.price = 3999.95;
        //获取手机对象的值
        System.out.println(p.brand);
        System.out.println(p.price);
        //调用手机中的方法
        p.call();
        p.playgame();
    }
}

创建一个对象分为两个步骤:声明对象变量和对象的实例化;

声明对象:变量并没有创建对象,系统只是为其分配一个引用空间;

对象的实例化:通过new关键字进行对象的实例化 实例化过程:为对象分配空间 执行构造方法完成初始化 返回对象的引用

a.为对象分配内存空间,并对成员变量进行初始化,数值型类型初值为0,逻辑型为false

b.执行显示初始化 执行类成员声明时带有的简单赋值表达式

c.执行构造方法,进行对象的初始化

        注意事项:a.类的首字母建议大写,类名需要见名知意,驼峰模式;

                          b.一个Java文件中可以定义多个class类,且只能有一个类是public修饰的,而且public修饰的类名必须是代码文件,实际开发中还是一个文件定义一个类

                          c.成员变量的完整定义格式:修饰符 数据类型 变量名称 = 初始化值,一般无需指定初始化值,存在默认值(基本数据类型默认值是0/0.0/false,引用数据类型的默认值是null)

2.成员方法

 方法调用中参数传递的方式:

Java中方法调用的参数传递的方式是传值,即方法调用不会改变调用程序中作为方法参数的变量的值。但是,当方法的参数类型是对象或者数组时候,在方法调用中传递给该参数的仍然是调用程序中对应变量的值,但是如果对该参数进行了修改(如修改成员变量的值),这种修改时永久的

p77-p79

可变参数列表

定义格式一般为:类型...参数名 int...nums 表示存放在nums中的类型为int的一组参数

可变参数类型只能做为方法参数列表中的最后一个参数

二.封装——对象代表什么,就得封装对应的数据,并且提供数据对应的行为

封装告诉我们拿到一个需求之后,如何正确设计对象的属性和方法

1.private 权限修饰符——保证数据的安全性

        a.可以修饰类的成员变量和成员方法,被private修饰的成员只能在本类中才能被访问;

        b.用private实现对非法数据的过滤:针对每一个私有化的变量成员,都为其提供一个get和set的方法,set方法给成员变量赋值(不需要返回值,需要形参),get方法对外提供成员变量的值(需要返回值,返回值类型与成员类型一致,不需要形参)

    public class phone{
       private String brand;
       private double price;

        public void setBrand(String b){
           brand=b;
       }//给外界的对象进行赋值的,所以需要形参,不需要返回值
        public  String getBrand(){
           return brand;
        }//对外提供brand属性的

        public void setPrice(double p){
           if (p >=1000 && p<=3000){
               price = p;
           }else{
               System.out.println("非法参数");
           }
        }
        //只有满足在1000-3000的范围内,才会被赋值
        public double getPrice(){
            return price;
        }
        public void call(){
            System.out.println("打电话");
        }
        public void playgame(){
            System.out.println("玩游戏");
        }
    }
public class phonetest {
    public static void main(String[] args){
        //创建手机对象
        phone p = new phone();

        //给手机赋值
//        p.brand = "小米";
//        p.price = 3999.95;
        p.setBrand("红米");
        p.setPrice(3000000);  //输出 非法参数

        //获取手机对象的值
      System.out.println(p.getBrand());//输出 红米
      System.out.println(p.getPrice());//输出 0.0

        System.out.println("__________________");
        //调用手机中的方法
        p.call();
        p.playgame();
    }
}
三.this关键字——作用是区分成员变量和局部变量

1.成员变量和局部变量(方法里面的变量)

        当成员变量和局部变量同名的时候,采用就近原则;在方法中,如果想用成员变量就用this.变量名;

    public class phone{
       private String brand;
       private double price;

        public void setBrand(String brand){
            //等号的右边 局部原则 表示的是测试类中调用方法传递过来的数据 "红米"
            //等号的左边 表示成员位置的name
           this.brand=brand;
       }
        public  String getBrand(){
           return brand;
        }
        public void setPrice(double price){
           if (price >=1000 && price<=3000){
               this.price = price;
           }else{
               System.out.println("非法参数");
           }
        }
        public double getPrice(){
            return price;
        }
    }
四.构造方法

对象都有构造方法 如果没有,编译器加一个构造方法(如果有系统就不会添加无参构造) 抽象类(不能new创建实例 但是也有构造方法)

构造方法也叫构造器,构造函数,作用是在创建对象的时候给成员变量进行赋值的,初始化

1.构造方法的格式

        修饰符 类名(参数){方法体}

权限修饰符为public:表示任何类都能创建这个类的实例对象

protected:表示只有这个类的子类或者在同一个包中的类能够创建实例对象

default:只有与该类在同一个包中的类可以创建这个类的实例对象

private:没有其他类可以实例化该类

在构造方法里面可以调用本类或者父类的构造方法,this调用本类的其他构造方法;super调用直接父类的构造方法(this和super要放在第一条语句 而且只能有一条)

2.注意事项

        a.方法名与类名相同,大小写也要一致

        b.没有返回值类型,连void也没有

        c.没有具体的返回值(不能由return带回结果数据)

        d.创建对象的时候由虚拟机调用,不能手动调用构造方法;每创建一次对象,就会调用一次构造方法

3.无参构造和带参构造

如果在类中没有定义构造方法,系统将给出一个默认的无参构造方法;如果定义了构造方法,系统将不再提供默认的构造方法,在实际开发中,最好写上无参构造和带全部参数的构造方法

        a.无参构造:初始化对象的时候,成员变量的数据均采用默认值; 给成员赋值的话,就用set方法        数值型: 0 | boolen型:false | char:'\0'  |对象:null  

        b.带参构造:初始化对象的时候,同时可以为对象进行赋值

    public class phone{
       private String brand;
       private double price;
       //空参构造
       public phone(){
           System.out.println("执行");
       }
       //带参数的构造
       public phone(String brand,double price){
           this.brand = brand;
           this.price = price;
       }
        public void setBrand(String brand){
           this.brand=brand;
       }
        public  String getBrand(){
           return brand;
        }
        public void setPrice(double price){
           if (price >=1000 && price<=3000){
               this.price = price;
           }else{
               System.out.println("非法参数");
           }
        }
        public double getPrice(){
            return price;
        }
    }
public class phonetest {
    public static void main(String[] args){
    //创建手机对象
        //调用的空参构造
        phone p = new phone();
        //调用空参构造,如果想要赋值的话,就用setBrand,setPrice
        p.setBrand("红米");
        p.setPrice(2400);

        //带参构造
        phone p1 = new phone("小米",2300);

    //获取
        System.out.println(p.getBrand());//输出红米
        System.out.println(p.getPrice());//输出2400
        System.out.println(p1.getBrand());//输出小米
        System.out.println(p1.getPrice());//输出2300

    }
}
4.重载构造方法

为了使用方便,可以对一个类定义多个构造方法,这些构造方法都有相同名称(类名),方法的参数不同(参数类型或参数个数不一样),称之为构造方法的重载

一个构造方法可以通过this关键字调用另外一个重载的构造方法

实例化时传入的参数不同,使用不同的构造方法

p85 重载构造方法的目的是使类对象有不同的初始值,为类对象的初始化提供方便

package jichuTest;

class Person
{
    String name;
    int age;
    Person(){}
    Person( String name, int age ){
        this.name=name; this.age=age;
        System.out.println("In Person(String,int)");
    }
}

class Student extends Person
{
    String school;
    Student(){
        this( null, 0, null );
        System.out.println("In Student()");
    }
    Student( String name, int age, String school ){
        super( name, age );
        this.school = school;
        System.out.println("In Student(String,int,String)");
    }
}

class Graduate extends Student
{
    String teacher="";
    Graduate(){
        //super();  不写这句话 会自动调用父类的无参构造
        System.out.println("In Graduate()");
    }
}
//一层一层调用 最终会调用到object
//In Person(String,int)
//In Student(String,int,String)
//In Student()
//In Graduate()
6.构造方法的执行过程

 先调用本类或父类的构造方法,直到最高一层object;再按声明顺序执行字段初始化赋值;执行构造函数中的各语句  尽量在构造器中不要调用任何方法,可能还没有赋值 唯一能够安全调用的就是带有final属性的方法

package jichuTest;

class ConstructSequence {
    public static void main(String[] args) {
        Student p = new Student("2222", 18, "信息工程");
    }
}

class Person {
    String name = "111";   //step 2
    int age = 1;        
    Person(String name, int age) {
        // Java中Object类是所有类的父类,调用super()在这里是隐式的,指向Object的构造器
        super(); // 这行可以省略,因为Object()是默认调用的  //step 1
        //step 3
        // 输出调用Person构造器前的状态
        System.out.println("调用Person构造器前,此时this.name=" + this.name + ", this.age=" + this.age);

        // 调用构造器后重新赋值
        this.name = name;
        this.age = age;

        // 输出调用Person构造器后的状态
        System.out.println("Person构造器调用后,此时this.name=" + this.name + ", this.age=" + this.age);
    }
}

class Student extends Person {
    String school = "未知学校"; //step2

    Student(String name, int age, String school) {
        // 调用父类Person的构造器
        super(name, age);//step 1

        //step3
        // 输出调用Student构造器前的状态
        System.out.println("调用Student构造器前,此时this.name=" + this.name + ", this.age=" + this.age + ", this.school=" + this.school);

        // 调用构造器后重新赋值school
        this.school = school;

        // 输出调用Student构造器后的状态
        System.out.println("Student构造器调用后,此时this.name=" + this.name + ", this.age=" + this.age + ", this.school=" + this.school);
    }
}
//调用Person构造器前,此时this.name=111, this.age=1
//Person构造器调用后,此时this.name=2222, this.age=18
//调用Student构造器前,此时this.name=2222, this.age=18, this.school=未知学校
//Student构造器调用后,此时this.name=2222, this.age=18, this.school=信息工程
五.标准的javaBean类

要求:1.类名需要见名知意   2.成员变量使用private修饰   3.至少提供两个构造方法(无参构造,带全部参数的构造)    4.成员方法(提供每一个成员变量对应的set()/get())

安装插件ptg一键生成

六.对象内存图

1.方法区:字节码文件加载时进入的内存;栈:方法运行时所进入的内存,变量也是在这里; 堆:new出来的东西会在这块内存中开辟空间并且产生新的地址;

2.一个对象的内存图

        student s = new student();

        a.加载class文件到方法区 b.声明局部变量 c.在堆内存中开辟一个空间 4.默认初始化 5.显示初始化 6.构造方法初始化

3.两个引用指向同一个对象     

        

4.this的内存原理

this的本质:代表方法调用者的地址值

七.对象清除与垃圾回收

 对象的自动清除叫做垃圾回收 对象是由Java虚拟机的垃圾回收线程来完成的

        

垃圾收集器的对象是被确认不存在任何引用的对象,一个变量保存的引用在改变量的作用域内有效,在变量的作用域外,引用将不存在,也可以显示的删除一个对象的引用,方法是将该引用型变量的值赋为null;

对象的最终化处理:

        只有经过最终化处理的对象,才意味着被废弃

t        ry-with-resources:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值