Java类和对象

序言

类和对象是OP语言的一个重要的知识点,抽象性很高,我们学习起来可能会有一些疑惑,今天我们好好谈谈这个知识点,若有错误,还请诸位斧正。

初阶

在初阶里面我们需要理解什么是类,如何实例化一个对象。

类(英语:class)在面向对象编程中是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的特性和方法。 支持类的编程语言在支持与类相关的各种特性方面都多多少少有一些微妙的差异。大多数都持不同形式的类继承。许多语言还支持提供封装性的特性,比如访问修饰符。类的出现,为面向对象编程的三个最重要的特性( 封装性、继承性、多态性 ),提供了实现的手段。 来源:(维基百科)

对象

在计算机科学中,对象(英语:object),台湾译作 " 物件 ",是一个存储器地址,其中拥有值,这个地址可能有标识符指向此处。对象可以是一个变量,一个数据结构,或是一个函数。是面向对象(Object Oriented)中的术语,既表示客观世界问题空间(Namespace)中的某个具体的事物,又表示软件系统解空间中的基本元素。 在软件系统中,对象具有唯一的标识符,对象包括属性(Properties)和方法(Methods),属性就是需要记忆的信息,方法就是对象能够提供的服务。在面向对象(Object Oriented)的软件中,对象(Object)是某一个类(Class)的实例(Instance)。 来源:维基百科

总结

  • 类就是一个模子 我们根据这个模子来造东西
  • 对象就是一个实体,我们通过模子构造出的实体

正式内容

类的组成

我们来看看类的组成。

class 类名 {

      字段;(或者称 成员属性)
      方法;
}

我们以一个例子来具体看看类的组成

class Person {

    public String name;   //允许赋值
    public int age;

    public static int size = 10;
    
    public void eat() {

         //注意 在方法内部只可以定义局部变量
         // public int a = 10;  报错
        System.out.println("eat!!!");
    }
    
    public static void sleep() {
        
        System.out.println("sleep!!!");
    }
}

字段

字段 又称 “成员变量”,像下面的 name、 age、size 就是字段,这里的的字段又分为两种

  • 实例成员变量 未用static修饰
  • 静态成员变量 用static修饰
public String name;   //允许赋值
public int age;
public static int size = 10;

这些不同留在下面说

方法

方法又称行为。类中的方法也分为两种,和字段一样看static是否修饰

由于静态成员变量开辟在方法区,所以可以说不在对象里面,可以这样说我们可以开辟多个对象,但这些对象“ 共用 ”静态成员变量

  • 实例成员方法
  • 静态成员方法
    public void eat() {       //实例成员方法
    
            System.out.println("eat!!!");
        }
        
        public static void sleep() {   //静态成员方法   用static
            
            System.out.println("sleep!!!");
        }

    至于这两者的不同,我后面会重点谈到,先放一放

    实例化一个对象

    一个类可以实例化多个对象,在堆上开辟相应的空间

    class Person {
    
        //实例成员变量
        public String name;
        public int age;
        //静态成员变量
        public static int size = 10;
        //实例成员方法
        public void eat() {
    
            System.out.println("eat!!!");
        }
        //静态成员方法
        public static void sleep() {
    
            System.out.println("sleep!!!");
        }
    }
    
    public class TestDemo2 {
    
        public static void main(String[] args) {
    
            Person per = new Person();//实例化一个对象
        }
    }

    重点讲解static

    static修饰与否会产生天差地别的不同

    字段的不同

    使用的不同

  • public class TestDemo2 {
    
        public static void main(String[] args) {
    
            Person per = new Person();
    
            per.age = 10;          //引用对象
            Person.size = 20;      //引用类  static修饰的字段和方法使用时需要引用类名  
        }
    }

    开辟空间的位置不同

    Java类和对象_第1张图片

  • 实例成员变量在  上开辟
  • 静态成员变量在方法区去开辟
  • Java类和对象_第2张图片

    由于静态成员变量开辟在方法区,所以可以说不在对象里面,可以这样说我们可以开辟多个对象,但这些对象“ 共用 ”静态成员变量

     

public class TestDemo2 {

    public static void main(String[] args) {

        Person per1 = new Person();
        Person per2 = new Person();

        per1.age = 10;
        Person.size = 20;

        System.out.println(per1.age);
        System.out.println(per2.age);
        System.out.println(Person.size);

    }
}

 

Java类和对象_第3张图片

方法的不同

某种意义上,静态成员方法的的要求更为严格,限制更多,这里我就不截图的

  • 静态成员方法只能调用静态成员方法,而实例成员方法不做要求
  • 静态成员方法里面不能出现实例成员变量,而而实例成员方法不做要求

访问修饰限定符

我们刚才谈了很多,不过有一个词没有谈到,就是public。public是一个访问修饰限定符,让我们看看这些内容都有什么。这里我们重点谈的是private,也就不的不提到 封装

访问修饰限定符

  • public: 共有的
  • private: 私有的
  • protected 受保护的
  • default : 默认权限 -> 包访问权限(后面会说)

封装

在面向对象编程方法中, 封装 (英语:Encapsulation)是指,一种将抽象性函数接口的实现细节部分包装、隐藏起来的方法。同时,它也是一种防止外界调用端,去访问对象内部实现细节的手段,这个手段是由编程语言本身来提供的 。 来源:维基百科

我们通过private将自己的写的方法封装起来,避免用户随意修改我们的代码,另外提供一个接口,方便用户使用。

class Person {

   private String name;  //封装
   private int age;

    public void setName(String name) {

        this.name = name;    //this是一个关键字
    }

    public void setAge(int age) {

        this.age = age;
    }

    public String getName() {

        return name;
    }

    public int getAge() {

        return age;
    }
}

public class TestDemo2 {

    public static void main(String[] args) {

        Person per = new Person();
        per.setAge(18);
        per.setName("读者");
        System.out.println(per.getName());
        System.out.println(per.getAge());
    }
}

 

Java类和对象_第4张图片

this关键字我们这里现在是不谈,后面我会再写一篇博客将关键字好好的的谈一谈,在这里我们就需要知道this.data 代表对象里的字段就可以了

构造方法

构造方法也是一种方法,不给他比较特殊

  1. 构造方法的类名和方法名相同
  2. 没有返回值,注意 是没有,而不是返回值是void

一个对象的产生分为几步 两步

  1. 为对象分配内存
  2. 调用合适的构造方法 

也就是说 构造方法一定参与对象的实例化

class Person{

    public String name;
    public int age;

    public Person() {    //构造方法

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

public class TestDemo2 {

    public static void main(String[] args) {

        Person per = new Person();

    }
}

上面的 Person() 就是一个构造方法。

  • 问:之前我们也没有写过构造方法啊,为什么还可以实例化对象? 答:因为编译器自动帮我们写了一个不带参数的构造方法,我们就不需要构造了
  • 问:构造方法是如何调用的? 答: Person per = new Person();中的Person(),就是调用

问题一

class Person{

    public String name;
    public int age;

    public Person(String name) {

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

public class TestDemo2 {

    public static void main(String[] args) {

        Person per = new Person();

    }
}

Java类和对象_第5张图片

  • 为什么会报错 答:当我们自己写构造方法时,编译器便不再为我们自动生成了,我们实例化对象时调用的构造方法参数不对

问题二

  • 问:可以存在多个构造方法吗 答:可以 构造方法也是遵从函数重载的

样例一

class Person{

    public String name;
    public int age;

    public Person() {

        System.out.println("构造方法1");
    }
    public Person(String name) {

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

public class TestDemo2 {

    public static void main(String[] args) {

        Person per = new Person();

    }
}

 

Java类和对象_第6张图片

样例二

class Person {
    public String name;
    public int age;
    public Person() {
        this.sleep();
    }
    public Person(String name) {
        this(11);
        //this();
        this.name = name;
    }
    public Person(int age) {
        this.age = age;
    }
    public void sleep() {
        System.out.println("sleep()");
    }
}

 

问题三

  • 问:构造方法可以互相调用吗 答: 可以,不过this()调用时只能在第一行,也就是说一个构造方法只能调用一次另一个
class Person{

    public String name;
    public int age;

    public Person() {

        System.out.println("构造方法1");
    }
    public Person(String name) {

        this();
        System.out.println("构造方法2");
    }
}

public class TestDemo2 {

    public static void main(String[] args) {

        Person per = new Person("xm");

    }
}

 

Java类和对象_第7张图片

代码块

代码块这个知识点我们不太常用,不过为了知识的完整性,我们还是把这个模块说一下吧.代码块分为以下几种

  1. 普通代码块 定义在方法中的代码块
  2. 构造块 定义在类中的代码块(不加修饰符)。也叫: 实例代码块 。构造代码块一般用于初始化实例成员变量
  3. 静态块 使用static定义的代码块。 一般用于初始化静态成员属性
  4. 同步代码块 这个不说

这里我们重点说一下构造快和静态块,下面一个代码就可以搞定

==从下面我们可以看出,静态块先执行,接着是实例代码块,后面才是构造方法.==这个顺序大家先记住.

class Test {

    public  int age;
    {
        System.out.println("这是一个 实例代码块 !!!");
    }
    static {
        System.out.println("这是一个静态代码块 !!!!");
    }

    public Test() {
        System.out.println("这是一个构造方法!!");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Test test = new Test();
    }
}

 

Java类和对象_第8张图片

进阶

看完上面的内容,想来你已经对类和对象有一定的了解了。下面的知识是关于一些常见问题的解答。我们一起来看看.

来看看这些问题把

下面代码是否可以编译通过

public class TestDemo { public int data; public static int n = 20; public static void main(String[] args) { TestDemo testDemo = new TestDemo(); this.n = 10; } } 

很抱歉,this关键字是对当前对象的引用,static修饰的成员变量和成员方法不在 对象 里面,所以编译不通过

Java类和对象_第9张图片

下面的代码是不是报错.

class Test { public static int age = 18; } public class TestDemo { public static void main(String[] args) { Test test = null; System.out.println(test.age); System.out.println(Test.age); } }

不会报错,static修饰的变是不属于对象的,即使我们没有new对象,也会得到结果

Java类和对象_第10张图片

那我们再看看下面的代码

 

class Test { public static int n = 10; public static void hello() { static int m = 20; } public void func() { static int k = 20; } } 

 

这个更简单,由static修饰的变量 定义 在方法区中,无论是静态方法还是普通成员方法

Java类和对象_第11张图片

看看下面的代码块静态代码块只能出现一次

class Test { public int age; { System.out.println("这是一个 实例代码块 !!!"); } static { System.out.println("这是一个静态代码块 !!!!"); } public Test() { System.out.println("这是一个构造方法!!"); } } public class TestDemo { public static void main(String[] args) { Test test1 = new Test(); System.out.println("================"); Test test2 = new Test(); } }

Java类和对象_第12张图片

总结一点

  1. 静态的成员是不能在方法中定义的
  2. this关键字无法引用static修饰的方法或者变量
  3. 静态代码块只能出现一次,即使不用实例化对象也可以执行,具体需要到JVM才可以.

你可能感兴趣的:(java,开发语言)