类是一种抽象的数据类型,它描述了一类对象的行为和状态。例如,我们可以定义一个名为“Dog”的类,它描述了狗这类动物的一般特性,如颜色、品种等状态,以及跑、叫等行为。
对象则是类的实例,也即具体化,代表了类定义的实体。比如,一条具体的狗可以被看作是“Dog”这个类的一个对象。它拥有该类中定义的各种属性(如颜色、名字、品种等)和方法(如跑、叫等)。因此,可以说对象是类的实现,而类则是对象的定义。
语法:
// 创建类 class
{ field;//成员属性 method;//成员方法 } // 实例化对象 <对象名> = new (); 其中class为类的关键字,classname是类名,{}中的就是方法主体,类中变量称之为类的成员变量,方法称之为成员方法
举例
class Person { public int age;//成员属性 实例变量 public String name; public String sex; public void eat() {//成员方法 System.out.println("吃饭!"); } public void sleep() { System.out.println("睡觉!"); } }
类的实例化
public class Main{ public static void main(String[] args) { Person person = new Person();//通过new实例化对象 person.eat();//成员方法调用需要通过对象的引用调用 person.sleep(); //产生对象 实例化对象 Person person2 = new Person(); Person person3 = new Person(); } }
输出结果为
吃饭!
睡觉!
类的成员可以包含以下:字段、方法、代码块、内部类和接口等,本篇为基础篇,介绍前三个.
3.1字段/属性/成员变量(用来描述一个类中有哪些数据)
举例:
class Person { public String name; // 字段 public int age; } class Test { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name); System.out.println(person.age); } } // 执行结果 null 0
由于name和age是全局变量,所以打印出初始值
注:
使用 . 访问对象的字段.
"访问" 既包含读, 也包含写.
对于一个对象的字段如果没有显式设置初始值, 那么会被设置一个默认的初值默认值规则 对于各种数字类型, 默认值为 0. 对于 boolean 类型, 默认值为 false. 对于引用类型(String, Array, 以及自定制类), 默认值为 null
我们不用默认值,也可以就地初始化,此时实例化对象时就有一个初值.
class Person { public String name = "张三"; public int age = 18; }
3.2 方法(描述一个对象的行为)
举例如下:
class Person { public int age = 18; public String name = "张三"; public void show() { System.out.println("我叫" + name + ", 今年" + age + "岁"); } } class Test { public static void main(String[] args) { Person person = new Person(); person.show(); } } //结果 我叫张三, 今年18岁
3.3 static 关键字
可以用来
1.修饰属性
2.修饰方法
3.代码块4.修饰类(暂时不谈)
1.修饰属性
修饰属性就是同一个类的不同实例共用同一个静态属性.就是我多个对象操作的是一个属性.举例:
class TestDemo{ public int a; public static int count; } public class Main{ public static void main(String[] args) { TestDemo t1 = new TestDemo(); t1.a++; TestDemo.count++; System.out.println(t1.a); System.out.println(TestDemo.count); System.out.println("============"); TestDemo t2 = new TestDemo(); t2.a++; TestDemo.count++; System.out.println(t2.a); System.out.println(TestDemo.count); } } 输出结果 1 1 ============ 1 2
内存结构
2.修饰方法
静态方法属于类,而不属于类的对象。
可以直接调用静态方法,而无需创建类的实例。
静态方法可以访问静态数据成员,并可以更改静态数据成员的值注:随着类的加载而加载
举例:class TestDemo{ public int a; public static int count; public static void change() { count = 100; //a = 10; error 不可以访问非静态数据成员 } } public class Main{ public static void main(String[] args) { TestDemo.change();//无需创建实例对象 就可以调用 System.out.println(TestDemo.count); } }
注:this和super不能在静态方法中使用,因为静态方法跟随类的加载而加载,this和super作用于对象,产生时间晚于static方法的加载.
4.1 private实现封装
被 public 修饰的成员变量或者成员方法, 可以直接被类的调用者使用.
被 private 修饰的成员变量或者成员方法, 不能被类的调用者使用假如我在类中使用private修饰一个成员变量,此时外界创建实例不能对此变量进行获取和修改,这就实现了封装,我不想将这一条属性让外界知道.
后面假如我又想修改或者查看了,这里我们就引出了getter()和setter()方法
class Person { private String name = "张三"; private int age = 18; public void show() { System.out.println("我叫" + name + ", 今年" + age + "岁"); } } class Test { public static void main(String[] args) { Person person = new Person(); person.age = 20; person.show(); } } // 编译出错 Test.java:13: 错误: age不可以在Person中访问private person.age = 20; ^ 1 个错误
下面我们给出get和set方法的使用实例class Person { private String name;//实例成员变量 private int age; public void setName(String name){ //name = name;//不能这样写 this.name = name;//this引用,表示调用该方法的对象 } public String getName(){ return name; } public void show(){ System.out.println("name: "+name+" age: "+age); } } public static void main(String[] args) { Person person = new Person(); person.setName("caocao"); String name = person.getName(); System.out.println(name); person.show(); } // 运行结果 caocao name: caocao age: 0
getName 即为 getter 方法, 表示获取这个成员的值.
setName 即为 setter 方法, 表示设置这个成员的值
快捷键 alt+insert
下面介绍构造方法(一种特殊的方法).使用关键字new实例化新对象时会被自动调用, 用于完成初始化操作
new 关键字的执行流程
1.为对象分配内存空间
2.调用对象的构造方法
构造方法的语法1.方法名称必须与类名称相同
2.构造方法没有返回值类型声明
3.每一个类中一定至少存在一个构造方法(没有明确定义,则系统自动生成一个无参构造)
注:如果指明了构造方法,编译器将不提供空参的构造方法this关键字
this表示当前对象引用(注意不是当前对象). 可以借助 this 来访问对象的字段和方法
这里构造方法中可以调用其他的构造方法,但是必须放在构造方法的第一行,原因是先创建对象才能调用方法.
举例:
class Person { private String name;//实例成员变量 private int age; private String sex; //默认构造函数 构造对象 public Person() { //this调用构造函数 this("bit", 12, "man");//必须放在第一行进行显示 } //这两个构造函数之间的关系为重载。 public Person(String name,int age,String sex) { this.name = name; this.age = age; this.sex = sex; } public void show() { System.out.println("name: "+name+" age: "+age+" sex: "+sex); } } public class Main{ public static void main(String[] args) { Person person = new Person();//调用不带参数的构造函数 person.show(); } } // 执行结果 name: bit age: 12 sex: man
代码块分为四种
普通代码块
构造块
静态块
同步代码块(暂时不谈)1.普通代码块(很少用)不影响代码的执行
public class Main{ public static void main(String[] args) { { //直接使用{}定义,普通方法块 int x = 10 ; System.out.println("x1 = " +x); } int x = 100 ; System.out.println("x2 = " +x); } } // 执行结果 x1 = 10 x2 = 100
2.构造代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量
举例:
class Person{ private String name;//实例成员变量 private int age; private String sex; public Person() { System.out.println("I am Person init()!"); } //实例代码块 { this.name = "bit"; this.age = 12; this.sex = "man"; System.out.println("I am instance init()!"); } public void show(){ System.out.println("name: "+name+" age: "+age+" sex: "+sex); } } public class Main { public static void main(String[] args) { Person p1 = new Person(); p1.show(); } } // 运行结果 I am instance init()! I am Person init()! name: bit age: 12 sex: man
直接显示初始化和用实例代码块初始化的区别?
一个是造出来这个对象的默认值,一个则是初始化之后用这个对象进行赋值的.
3.静态代码块
随着类的加载而执行(先于构造方法),只能访问静态成员,一般用于给静态成员初始化
举例如下class Person{ private String name;//实例成员变量 private int age; private String sex; private static int count = 0;//静态成员变量 由类共享数据 方法区 public Person(){ System.out.println("I am Person init()!"); } //实例代码块 { this.name = "bit"; this.age = 12; this.sex = "man"; System.out.println("I am instance init()!"); } //静态代码块 static { count = 10;//只能访问静态数据成员 System.out.println("I am static init()!"); } public void show(){ System.out.println("name: "+name+" age: "+age+" sex: "+sex); } } public class Main { public static void main(String[] args) { Person p1 = new Person(); Person p2 = new Person();//静态代码块是否还会被执行?会 } }