对象&类

  • 对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
  • :类是一个模板,它描述一类对象的行为状态


java命名约定的优点

通过使用标准的Java命名约定,您可以使自己和其他程序员更容易阅读代码。Java程序的可读性非常重要。 它能让程序开发者花费更少的时间来读懂代码的作用。

名称

约定

类名称

应以大写字母开头,并成为容易理解的名词或组合。如:String, Color, Button, System, Thread等。

接口名称

应以大写字母开头,并作为形容词。如: RunnableRemoteActionListener等。

方法名称

应以小写字母开头,并作为动词。如:actionPerformed()main()print()println()等。

变量名称

应以小写字母开头。如:firstNameorderNumber等。

包名称

应使用小写字母。如: javalangsqlutil等。

常量名称

应使用大写字母。 例如:RED, YELLOW, MAX_PRIORITY


1、Java变量类型

Java中的每个变量都有一个类型,它决定了变量内存的大小和布局; 可以存储在该存储器中的值的范围; 以及可以应用于变量的操作集。

变量需要先声明才能使用,以下是变量声明的基本形式 -

data type variable [ = value][, variable [ = value] ...] ;

这里data type是Java的数据类型之一,variable是变量的名称。要声明具有相同类型的多个变量,可以使用逗号分隔列表。

Java中有三种变量 -

  • 局部变量
  • 实例变量
  • 类/静态变量

1. 局部变量

  • 局部变量一般在方法,构造函数或块中声明
  • 程序进入方法,构造函数或块时会创建局部变量,并且一旦退出方法,构造函数或块,变量就会销毁。
  • 访问修饰符不能用于局部变量。
  • 局部变量仅在声明的方法,构造函数或块中可见。
  • 局部变量在内部实现堆栈级别。
  • 局部变量没有默认值,因此应声明局部变量后,在第一次使用之前为它分配初始值

示例  在这里,age是一个局部变量。 这是在dogAge()方法中定义的,它的范围仅限于此方法。

public class Test {
   public void getAge() {
      int age = 0;
      age = age + 5;
      System.out.println("Dog age is : " + age);
   }

   public static void main(String args[]) {
      Test test = new Test();
      test.getAge();
   }
}

执行上面示例代码,得到以下结果:

Dog age is : 5

2. 实例变量


  • 实例变量类中声明,但在方法,构造函数或块之外
  • 为堆中的对象分配空间时,将为每个实例变量值创建一个槽。
  • 使用关键字new创建对象时会创建实例变量,并在销毁对象时销毁实例变量。
  • 实例变量包含由多个方法,构造函数或块引用的值,或者在整个类中存在的对象状态的基本部分。
  • 实例变量可以在使用之前或之后在类级别中声明。
  • 可以为实例变量给出访问修饰符。
  • 实例变量对于类中的所有方法,构造函数和块都是可见的。 通常,建议将这些变量设为私有(访问级别)。 但是,可以使用访问修饰符为这些变量提供子类的可见性。
  • 实例变量具有默认值。 对于数字,默认值为0,对于布尔值,它为false,对于对象引用,它为null。
  • 可以在声明期间或构造函数中指定值。可以通过调用类中的变量名来直接访问实例变量。 但是,在静态方法中(当实例变量具有可访问性时),应使用完全限定名称调用它们,如:ObjectReference.VariableName。
import java.io.*;
public class Employee {

   // 此实例变量对于子类都是可见的。
   public String name;

   // salary 变量仅在Employee类中可见。
   private double salary;

   // name变量在构造函数中指定。
   public Employee (String empName) {
      name = empName;
   }

   // 为 salary 变量赋值
   public void setSalary(double empSal) {
      salary = empSal;
   }

   // 此方法打印员工详细信息。
   public void printEmp() {
      System.out.println("name  : " + name );
      System.out.println("salary :" + salary);
   }

   public static void main(String args[]) {
      Employee empOne = new Employee("Maxsu");
      empOne.setSalary(15999);
      empOne.printEmp();
   }
}

执行上面示例代码,得到以下结果:

name  : Maxsu
salary :15999.0

3. 类/静态变量

  • 类变量(也称为静态变量)在类中使用static关键字声明,但在方法,构造函数或块之外
  • 每个类只有一个每个类变量的副本,无论从中创建多少个对象。
  • 除了声明为常量之外,很少使用静态变量。常量是声明public/privatefinalstatic的变量。常量的初始值不能更改。
  • 静态变量存储在静态存储器中。 除了声明的final之外,很少使用静态变量,并将其用作公共或私有常量。
  • 程序启动时会创建静态变量,程序停止时会销毁静态变量。
  • 可见性类似于实例变量。 但是,大多数静态变量都是公共的,因为它们必须可供该类用户使用。
  • 默认值与实例变量相同。 对于数字,默认值为0; 对于布尔类型来说,默认值为false; 对于对象引用,默认值为null。 可以在声明期间或构造函数中指定值。 此外,可以在特殊的静态初始化程序块中分配值。
  • 可以通过使用类名ClassName.VariableName调用来访问静态变量
  • 将类变量声明为public static final时,变量名(常量)都是大写的。 如果静态变量不是publicfinal,则命名语法与实例和局部变量命名规则相同。

示例

import java.io.*;
public class Employee {

   // salary变量是一个私有静态变量
   private static double salary;

   // DEPARTMENT是一个常量
   public static final String DEPARTMENT = "研发部";

   public static void main(String args[]) {
      salary = 19999;
      System.out.println(DEPARTMENT + "平均薪水:" + salary);
   }
}

执行上面示例代码,得到以下结果 -

研发部平均薪水:19999


2、构造方法

每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法

在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须同名,一个类可以有多个构造方法。

下面是一个构造方法示例:

public class Test{
    public Test(){
    }
 
    public Test(String name){
        // 这个构造器仅有一个参数:name
    }
}

3、创建对象

对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:

  • 声明:声明一个对象,包括对象名称和对象类型。
  • 实例化:使用关键字 new 来创建一个对象。 类名 对象名 = new 对象名()
  • 初始化:使用 new 创建对象时,会调用构造方法初始化对象。

下面是一个创建对象的例子:

public class Test{
   public Test(String name){
      //这个构造器仅有一个参数:name
      System.out.println("小狗的名字是 : " + name ); 
   }
   public static void main(String[] args){
      // 下面的语句将创建一个Test对象
      Puppy myTest = new Test( "tommy" );
   }
}


形参&实参

方法的定义可能会用到 参数(有参的方法),参数在程序语言中分为:

  • 实参(实际参数,Arguments):用于传递给函数/方法的参数,必须有确定的值。
  • 形参(形式参数,Parameters):用于定义函数/方法,接收实参,不需要有确定的值。
String hello = "Hello!";

// hello 为实参
sayHello(hello);

// str 为形参
void sayHello(String str) {
    System.out.println(str);
}


4、访问实例变量和方法

通过已创建的对象来访问成员变量和成员方法,如下所示:

/* 实例化对象 */
Object referenceVariable = new Constructor();
/* 访问类中的变量 */
referenceVariable.variableName;
/* 访问类中的方法 */
referenceVariable.methodName();


public class Dog{
   int dogAge;
   
   public Dog(String name){
      // 这个构造器仅有一个参数:name
      System.out.println("小狗的名字是 : " + name ); 
   }
 
   public void setAge( int age ){
       dogAge = age;
   }
 
   public int getAge( ){
       System.out.println("小狗的年龄为 : " + dogAge ); 
       return dogAge;
   }
 
   public static void main(String[] args){
      /* 创建对象 */
      Dog myDog = new Dog( "tommy" );
      /* 通过方法来设定age */
      myDog.setAge( 2 );
      /* 调用另一个方法获取age */
      myDog.getAge( );
      /*你也可以像下面这样访问成员变量 */
      System.out.println("变量值 : " + myDog.dogAge ); 
   }
}


5、this关键字

this 是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。在java中,这是一个引用当前对象的引用变量

java this关键字的用法如下:

  1. this关键字可用来引用当前类的实例变量。
  2. this关键字可用于调用当前类方法(隐式)。
  3. this()可以用来调用当前类的构造函数。
  4. this关键字可作为调用方法中的参数传递。
  5. this关键字可作为参数在构造函数调用中传递。
  6. this关键字可用于从方法返回当前类的实例。

//更多请阅读:https://www.yiibai.com/java/this-keyword.html


1. this:引用当前类的实例变量

如果实例变量和参数之间存在歧义,则 this 关键字可用于明确地指定类变量以解决歧义问题。

Public class Student {
    int rollno;
    String name;
    float fee;

    Student(int rollno, String name, float fee) {
        this.rollno = rollno;		// this.rollno指的是Student 
        this.name = name;
        this.fee = fee;
    }

    void display() {
        System.out.println(rollno + " " + name + " " + fee);
    }
}

class TestThis2 {
    public static void main(String args[]) {
        Student s1 = new Student(111, "ankit", 5000f);
        Student s2 = new Student(112, "sumit", 6000f);
        s1.display();
        s2.display();
    }
}
  • 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。

在上面的例子中,参数(形式参数)和实例变量(rollnoname)是相同的。 所以要使用this关键字来区分局部变量实例变量

2. this:调用当前类方法

可以使用this关键字调用当前类的方法。如果不使用this关键字,编译器会在调用方法时自动添加此 this 关键字。我们来看看这个例子。

Java学习—对象和类_构造函数

执行上面代码输出结果如下 -

hello n
hello m

3. this():调用当前类的构造函数

this()构造函数调用可以用来调用当前类的构造函数。 它用于重用构造函数。 换句话说,它用于构造函数链接。

参数化构造函数调用默认构造函数:   

new A(10) ---调用有参构造器

this()---调用无参构造器

class A {
    A() {
        System.out.println("hello a");
    }

    A(int x) {
        this();		// 调用有参构造器 A(){}
        System.out.println(x);
    }
}

class TestThis5 {
    public static void main(String args[]) {
        A a = new A(10);	// 调用有参构造器 A(int x){}
    }
}

执行上面代码输出结果如下 -

hello a
10

默认构造函数调用参数化构造函数:

new A() ---调用无参构造器

this(5)---调用有参构造器

class A {
    A() {
        this(5);	// 调用有参构造器 A(int x){}
        System.out.println("hello a");
    }

    A(int x) {
        System.out.println(x);
    }
}

class TestThis6 {
    public static void main(String args[]) {
        A a = new A();	// ---调用无参构造器 A(){}
    }
}

执行上面代码输出结果如下 -

5
hello a

使用this()构造函数调用

this()构造函数调用用于从构造函数重用构造函数。 它维护构造函数之间的链,即它用于构造函数链接。看看下面给出的示例,显示this关键字的实际使用。

class Student {
    int rollno;
    String name, course;
    float fee;

    Student(int rollno, String name, String course) {
        this.rollno = rollno;
        this.name = name;
        this.course = course;
    }

    Student(int rollno, String name, String course, float fee) {
        this(rollno, name, course);// reusing constructor
        this.fee = fee;
        
        // 不把 this() 语句放在第一行,因此编译不通过
        // this(rollno, name, course);    // C.T.Error报错
    }

    void display() {
        System.out.println(rollno + " " + name + " " + course + " " + fee);
    }
}

class TestThis7 {
    public static void main(String args[]) {
        Student s1 = new Student(111, "ankit", "java");
        Student s2 = new Student(112, "sumit", "java", 6000f);
        s1.display();
        s2.display();
    }
}

执行上面代码输出结果如下 -

111 ankit java null
112 sumit java 6000

注意:调用this()必须是构造函数中的第一个语句。

4. this:作为参数传递给方法

this关键字也可以作为方法中的参数传递。 它主要用于事件处理。 看看下面的一个例子:

class S2 {
    void m(S2 obj) {
        System.out.println("method is invoked");
    }

    void p() {
        m(this);
    }

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

执行上面代码输出结果如下 -

method is invoked

这个应用程序可以作为参数传递:

在事件处理(或)的情况下,必须提供一个类的引用到另一个。 它用于在多个方法中重用一个对象。


6. this关键字用来返回当前类的实例

可以从方法中 this 关键字作为语句返回。 在这种情况下,方法的返回类型必须是类类型(非原始)。 看看下面的一个例子:

作为语句返回的语法

return_type method_name(){  
    return this;  
}

从方法中返回为语句的 this 关键字的示例

class A {
    A getA() {
        return this;
    }

    void msg() {
        System.out.println("Hello java");
    }
}

class Test1 {
    public static void main(String args[]) {
        new A().getA().msg();
    }
}

执行上面代码输出结果如下 -

Hello java


验证 this 关键字

现在来验证 this 关键字引用当前类的实例变量。 在这个程序中将打印参考变量,这两个变量的输出是相同的。

class A5 {
    void m() {
        System.out.println(this);	// prints same reference ID
    }

    public static void main(String args[]) {
        A5 obj = new A5();
        System.out.println(obj);	// prints the reference ID
        
        obj.m();
    }
}

执行上面代码输出结果如下 -

A5@22b3ea59
A5@22b3ea59


6、抽象类abstract

抽象是隐藏实现细节并仅向用户显示功能的过程。

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用

Java学习—对象和类_System_02


快捷键---ARLT+回车

Animal类:

package com.test.abstracts;

public abstract class Animal {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
    public void drink() {
        System.out.println("动物喝水!");
    }
    
    // abstract抽象方法
    public abstract void eat();
    
}

Dog类:

package com.test.abstracts;

public class Dog extends Animal{
    public Dog() {
    }

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("狗吃骨头!");
    }
}

Sheep类:

package com.test.abstracts;

public class Sheep extends Animal{
    public Sheep() {
    }

    public Sheep(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("小羊吃草!");
    }
}

Test类:

package com.test.abstracts;

public class Test {
    public static void main(String[] args) {
        Dog d = new Dog("小灰灰" + ",年龄:",2);
        System.out.println(d.getName() + "," + d.getAge());
        d.eat();
        d.drink();
    }
}