定义

类和对象 - 图1 具体 —> 抽象
对象1,对象2 —> 类
多个对象,可以抽象出 类
类 可以产生多个对象

类和对象的组成部分

类和对象 - 图2

桌子:类
这个桌子:对象

类可以细分,但细分并不一定是对象。
人 —> 顾客 —> VIP会员 都是抽象范围,都是类

int num = 10;
String str = “zs” ;
类 对象 = 类() ;
Person zs = new Person();

属性:就是全局变量

全局变量:

方法以外,类以内,有初始值(数据类型的默认值 int 0)
String name;

局部变量:

方法以内,无初始值,使用前必须赋初值
可以和全局变量重名,并且优先级高,会覆盖全局
String name = “abc”;

类的定义

格式

class 类名称{ ** **//注意这里没有static因为此时定义的方法将要由对象调用,不像之前直接由主方法调用
数据类型 属性;

public 返回值的数据类型 方法名称 (参数1,参数2…){
程序语句;
return 表达式;
}
}

定义person类

  1. class Person{
  2. String name; //声明姓名属性
  3. int age; //声明年龄属性
  4. public void tell(){ //获取信息方法
  5. System.out.println("name:"+name+",age"+age);
  6. }
  7. }

在以上程序中,Person类定义了name和age两个属性,之后又定义了tell方法,此方法的功能就是打印这两个属性的内容。

对象的创建和使用

格式

类名 对象名称 = null;//声明对象
对象名称 = new 类名 () ; //实例化对象

类名 对象名称 = new 类名 () ; //创建并实例化对象

访问对象中的属性/方法

访问属性

对象名称 . 属性名

访问方法

对象名称 . 方法名()

new :实例化

对象使用前必须先实例化 new

范例

class Person{
  String name;            //声明姓名属性
  int age;                    //声明年龄属性
  public void tell(){            //获取信息方法
      System.out.println("name:"+name+",age"+age);
  }
}
public class ClassDemo02{
    public static void main(String arg[]){
      Person per = new Person();     //创建并实例化对象
    per.name="张三";             //为name属性赋值
    per.age=30;                 //为age属性赋值
    per.tell();                                    //调用类中的方法
  }
}

结果:
姓名:张三,年龄:30
public class Person {
    //静态  属性  
    //全局变量
    String name;  //只有属性名,没有属性值
    int age;

    //动态  方法
    //吃饭
    public void eat(){
        String name = “abc”;   //局部变量  可以和全局变量重名,并且优先级高,会覆盖全局
        System.out.println("吃饭..."); 
    }
    //睡觉
    public void sleep(){
        System.out.println("睡觉...");
    }
}
public class TestPerson {
    public static void main(String[] args) {
        //类 对象 = new 类() ;
        Person zs = new Person();  //Person zs;  
                                   //zs = new Person();

        //对象.属性
        zs.name = "张三";
        zs.age = 28;

        System.out.println(zs.name);
        System.out.println(zs.age);

        //对象.方法
        zs.eat();
        zs.sleep();

    }
}

/*
张三
28
吃饭...
睡觉...*/

方法 是对个对象共有的
属性 是各个对象独有的

Person zs = new Person();
一般而言,对象是指堆中的东西
栈里面zs的 称为引用

引用

相当于C中的指针。持有对象的内存地址

对象引用传递P101

将一个堆内存空间的使用权给多个栈内存空间,每个栈内存空间都可以修改堆内存的内容

eg:

创建两个对象,为两个对象引用属性之后,
per2 = per1 ;
这时per2指向per1的堆内存,而之前per2所占的堆内存就没有被任何栈内存空间引用了
此时出现垃圾空间

垃圾空间的释放

Java本身提供垃圾收集机制(Garbage Collecting,GC) ,会不定期的释放不用的内存空间,只要对象不使用了,就会等待GC释放空间
一个栈内存空间只能指向一个堆内存空间,要想再指其他的堆内存空间,必须先断开已有的指向才能分配新的。

封装性P103

面对对象的一大特性
所谓封装性,就是对外不可见
一般开发中往往要将类中的属性封装(private)

格式

属性封装

private 属性类型 属性名称 ;

方法封装

private 方法返回值 方法名称(参数列表){ }

eg:

class Person{
    private String name;
    private int age;
    public void tell(){
        System.out.println("name:"+name+" age:"+age);
    }
}
public class text1 {
    public static void main(String[] args) {
        Person per = new Person();
        per.name = "zs";   //错 ,无法访问封装属性
        per.age=-30;       //错
        per.tell();
    }
}
结果:
Error:(11, 12) java: name可以在Person中访问private
Error:(12, 12) java: age可以在Person中访问private

name和age是private的了啦,对象不能直接访问,保证了对口处有所限制。
只要是被封装的属性,则必须通过setter和getter方法设置取得。

来使用一下这个方式叭!

class Person{
    private String name;
    private int age;
    public void tell(){
        System.out.println("name:"+name+" age:"+age);
    }
    public String getName(){

        return name;        //取得姓名
    }
    public void setName(String n){
        name = n;          //设置姓名
    }
    public int getAge(){
        return age;        //取得年龄
    }
    public void setAge(int a){
        age = a;           //设置年龄
    }
}
public class text1 {
    public static void main(String[] args) {
        Person per = new Person();
        per.setName("zs");          //调用setter设置姓名
        per.setAge(-30);            //调用setter设置年龄
        per.tell();
    }
}

结果:
name:zs age:-30

在程序中可以发现通过setter和getter方法可以设置和取地属性,而在调用主方法时,也是调用了setter()方法进行的内容赋值。

如果想对设置进去的内容进行检查,也只需要在setter() 方法处加入检查代码即可。

class Person{
    private String name;
    private int age;
    public void tell(){
        System.out.println("name:"+name+" age:"+age);
    }
    public String getName(){      //取得姓名

        return name;
    }
    public void setName(String n){    //设置姓名

        name = n;
    }
    public int getAge(){       //取得年龄
        return age;
    }
    public void setAge(int a){   //设置年龄
        if (a>=0 && a<150){   //通过setter 在此处加上验证代码
            age = a;
        }else{
            System.out.println("真的有这个岁数的人类吗???");
        }
    }
}
public class text1 {
    public static void main(String[] args) {
        Person per = new Person();
        per.setName("zs");
        per.setAge(-30);
        per.tell();
    }
}

结果:
真的有这个岁数的人类吗???
name:zs age:0

tips:

类中全部属性必须封装,封装之后的属性必须通过setter和getter进行访问
用private声明的属性或方法只能在其内部使用,而不能在类的外部被调用

构造方法

为类的属性初始化,在对象实例化时就直接把对象的值赋给属性。
可视为一种特殊的方法

格式

class 类名称{ ** //名称必须与类名称一致
访问权限 类名称(类型1 参数1,类型2 参数2,…){
程序语句;
…. **//构造方法没有返回值
}
}

eg:

class Person{
    public Person(){
        System.out.println("一个新的Person对象产生咯!");
    }
}
public class text1 {
    public static void main(String[] args) {
        System.out.println("声明对象:Person per = null;");
        Person per = null;  //声明对象时不调用构造
        System.out.println("实例化对象: per = new Person();");
        per = new Person();    //实例化对象时调用构造
    }
}

结果:
声明对象:Person per = null;
实例化对象: per = new Person();
一个新的Person对象产生咯!
当调用关键字new  实例化对象时才会调用构造方法,只要是类就必定存在构造方法。<br />**P108 **<br />“只要是类就必定存在构造方法”  为什么之前没有构造方法也可以对象实例化?<br />不构造会发生什么?

eg2通过构造方法为类中的属性赋值

class Person{
    private String name;   //声明姓名属性
    private int age;       //声明年龄属性
    public Person(String name,int age){     //定义构造方法为属性初始化
        this.setName(name);      //为name属性赋值
        this.setAge(age);       //为age属性赋值
    }
      //取得信息的方法tell()
    public void tell(){   
        System.out.println("name:"+getName()+" ,age:"+getAge());
    }

    public String getName(){   //取得姓名
        return name;
    }

    public void setName(String a){  //设置姓名
        name = a;
    }

    public int getAge(){  //取得年龄
        return age;
    }

    public void setAge(int b){   //设置年龄
        if (b<0&&b>150){         //在此处加上验证代码

            System.out.println("我怀疑你出错了并且有足够的证据!");

        }else{
            age = b;
        }
    }


}
public class text1{
    public static void main(String[] args){  
        Person per = new Person("zs",30);  //调用构造方法,传递两个参数
        per.tell();
    }
}

结果:
name:zs ,age:30

这样赋值比用setter更方便(大概

eg3构造方法也可以重载P110

匿名对象

没有明确给出名称的对象
一般匿名对象只使用一次,只在堆内存中开辟空间,不存在栈内存引用
所以说匿名对象实际上就是一个堆内存空间,对象不管是匿名还是非匿名,都必须在开辟堆内存空间之后才能使用。

定义格式

new 类名 ;

eg

class Person{
    private String name;
    private int age;
    public Person(String name,int age){
        this.setName(name);
        this.setAge(age);
    }
    public void tell(){
        System.out.println("name:"+getName()+" ,age:"+getAge());
    }

    public String getName(){

        return name;
    }
    public void setName(String a){

        name = a;
    }

    public void setAge(int b){
        if (b<0&&b>150){
            System.out.println("我怀疑你出错了并且有足够的证据!");
        }else{
            age = b;
        }
    }
    public int getAge(){

        return age;
    }

}
public class text1{
    public static void main(String[] args){
        new Person("zs",30).tell();           //匿名对象
    }
}

主方法中可以发现,直接使用了 new Person(“zs”,30) 语句,这实际上就是一个匿名对象
节省内存,此处没有任何栈内存引用它,所以此对象使用一次之后就等待被垃圾收集机制回收。

匿名对象的作用

作为其他类实例化对象的参数传递

方法的调用 常见情况

同一个类中:

都有static,或都没有static,或没的调有的:直接调用
有static** 不能直接调用没有static的方法**

静态方法
public static void eatFruit(){…}

非静态方法
public void eatFruit(){…}

public class Person2 {
    //属性

    //方法
    public void eatFruit(){
        System.out.println("吃水果..");
    }
    public void eatFood(){
        System.out.println("吃主食..");
        eatFruit();  //调用eatFruit方法
    }

    public void sleep(){

    }

    public static void main(String[] args) {
        Person2 p = new Person2();
        p.eatFood(); //调用eatFood方法
    }

}


不在同一个类中:

万能方法:new 对象,对象.方法();
Person2 p = new Person2();
p.eatFruit();
调用的另一个方法必须是静态的(有static)
类名.方法()
Person2.eatFruit();

public class Person3 {
    public void aa() //public void static aa()
    {
        Person2 p = new Person2();
        p.eatFruit();

        Person2.eatFruit(); //类名.方法()  其中的方法必须是static修饰的
    }
    public void bb()
    {

    }

    public static void main(String[] args) {
        Person3 p = new Person3();
        p.aa();
    }
}

static方法 是 类级别的 属于类
非static方法 是 对象级别 ,属于对象

对象.static方法() | 对象.非static方法()
类.static方法()

类有的,对象自然有
对象有的,类不一定有