类及类的成员

类和对象

对象的创建和类的实例化

首先要理解类和对象的关系,和JS类似,类是对象的抽象概念,对象是类的实例化
一个小例子

类的创建

在IDEA中提供了方便的创建类的方法,存放类的文件名就是类名

public class ClassName {
	//属性
	//方法
}

对象创建

由public修饰的类可直接被其他类访问,使用构造函数的方法进行类的实例化,获得一个对象

class Main {
    public static void main(String[] args) {
        Phone p = new Phone();
    }
}

也可以创建一个匿名对象,直接访问方法和属性

new Phone().call();
new Phone().price;

通常作为参数传入方法

流程:

  1. 创建类
  2. 根据类创建对象
  3. 通过对象访问和修改类的属性和方法

对象的内存分析

对象数组

数组的元素可以是对象,称为对象数组
创建方法和其他数组相同

Person[] p = new Person[20];
for (int i = 0; i < p.length; i++) {
	p[i] = new Person();
}

但需要注意内部的每个元素还处于未初始化的状态,需要再次使用构造函数初始化,实际上访问方法也相同

for(Person per:p){
	System.out.println(per.age + " " + per.weight + " " + per.name);
}

类的成员

属性

变量的分类

变量按数据类型可划分为基本数据类型和引用数据类型,下面提出另一种分类方法:
根据变量在类中声明位置的不同分为

public class Phone {
    double price = 100.0;// 成员变量
    int amount = 100;// 成员变量
    public void call() {
        String number = "12345678";// 局部变量
        System.out.println("Call" + number);
    }
}

所以属性又称为成员变量

不同点:

属性赋值的先后顺序

  1. 默认初始化
  2. 显式初始化或代码块中初始化
  3. 构造器中初始化
  4. 通过对象.属性对象.方法的方法进行赋值

方法

声明

格式:

权限修饰符 [其他修饰符] 返回值类型 方法名(形参列表)[throws 异常类型]{
   // 方法体
}

方法的定义没有先后顺序
方法内不能定义方法

。。。实在没什么新东西。。。基础操作和C语言的函数逻辑基本一样

方法的重载

方法重载说明可以定义多个同名方法,指定不同参数来实现不同参数的相同逻辑

一道面试题参考:判断println的输出

可变个数形参的方法(JDK5.0新特性)

格式:

方法名(参数的类型名 ...参数名)

特点:

public void print(int... nums) {}
public void print(int[] nums) {}

二者使用方法相同,都是数组的使用,不同的是前者的调用不需要创建数组,依次传入参数即可:

PhoneTest p = new PhoneTest();
p.print(1, 2, 3, 4, 5);

一个实例:使用可变个数形参拼接字符串

方法中的值传递机制

这里和C有所不同,相同的是基本数据类型传递的是值,引用数据类型传递的是地址,但是Java中无法获得基本数据类型的地址,只能放在对象中,传入对象,改变其内部的局部变量的值

构造器

类的成员之三

权限修饰符 类名(形参列表){}

在IDEA中,使用alt+insert快捷插入指定变量的构造器IDEA 常用快捷键一览表#第2组:提高编写速度(上)

代码块

可以有输出语句,可以对类的属性、类的声明进行初始化操作,多个代码块,按照从上到下的顺序依次执行

静态代码块

static修饰,并且只能使用static修饰

public class BankTest {
    public static void main(String[] args) {
        System.out.println(Bank.info);
    }
}
class Bank {
    // 构造器私有化
    String name;
    int age;
    static String info="OK";

    {
        System.out.println("Unstatic");
        name = "Laoba";
        age = 18;
    }

    static {
        System.out.println("Static");
    }
}

输出为:

Static
OK

不会输出Unstatic

非静态代码块

public class BankTest {
    public static void main(String[] args) {
        Bank instance = new Bank();
    }
}

class Bank {
    // 构造器私有化
    String name;
    int age;
    static String info = "OK";
    {
        System.out.println("Unstatic");
        name = "Laoba";
        age = 18;
    }
    static {
        System.out.println("Static");
    }
}

输出为:

Static
Unstatic

应用
多个构造器的相同逻辑可以放在非静态代码块中执行

{
	System.out.println("新用户注册");
	registrationTime = System.currentTimeMillis();
	//获取系统当前时间 (距离1970-1-1 00:00:00的毫秒数)
}
//代码块的使用
public User1(){
	// System.out.println("新用户注册");
	// registrationTime = System.currentTimeMillis();
	userName = System.currentTimeMillis() + "";
	password = "123456";
}
public User1(String userName,String password){
	// System.out.println("新用户注册");
	// registrationTime = System.currentTimeMillis();
	this.userName = userName;
	this.password = password;
}

内部类

练习题:练习题#内部类
将一个类A定义在另一个类B里面,里面的那个类A就称为 内部类(InnerClass),类B则称为 外部类(OuterClass)
具体来说,当一个事物A的内部,还有一个部分需要一个完整的结构B进行描述,而这个内部的完整的结构B又只为外部事物A提供服务,不在其他地方单独使用,那么整个内部的完整结构B最好使用内部类
总的来说,遵循 高内聚、低耦合的面向对象开发原则

分类

类似于变量的分类

成员内部类

直接声明在外部类的里面,代码块、方法中

理解
创建成员内部类的实例
class Person {
    String name;
    static class Brain {}
    class Intelligence {}
}
Person.Brain brain = new Person.Brain();

即静态的成员可以直接被类访问

Person p1 = new Person();
Person.Intelligence i1= p1.new Intelligence();

非静态只能由实例调用,所以肯定要创建外部类的实例,但是内部类的实例创建写法有些特殊

访问外部类的结构
class Person {
    String name = "Perosn";
    public void love(){
        System.out.println("Love");
    }
    class Intelligence {
        String name = "Intelligence";
        public void fun() {
            System.out.println(name);// Intelligence
            System.out.println(this.name);// Intelligence
            System.out.println(Person.this.name);// Person
            Person.this.love();// Love
        }
    }
}

局部内部类

非匿名局部内部类
匿名局部内部类
定义在方法等类的结构中
格式:

[修饰符] class 外部类{
    [修饰符] 返回值类型  方法名(形参列表){
            [final/abstract] class 内部类{
    	}
    }  
}

基本使用:

public class OuterClassTest1 {
    //开发中的场景
    public Comparable getInstance(){
		//提供了实现了Comparable接口的类
        //方式1:提供了接口的实现类的对象
        class MyComparable implements Comparable{
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }
        MyComparable m = new MyComparable();
        return m;
        
        //方式2:提供了接口的实现类的匿名对象
        class MyComparable implements Comparable{
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }
        return new MyComparable();
        
        //方式3:提供了接口的匿名实现类的对象
        Comparable c = new Comparable(){
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
        return c;
        
        //方式4:提供了接口的匿名实现类的匿名对象
        return new Comparable(){
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };

    }



}