类和对象

栗子1:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Dog {
int size;
String name;

// 构造方法
public Dog() {
System.out.printLn("这是一个无参数的构造方法");
}

public void eat() {
System.out.printLn("这是一个吃的方法");
}
}
1
2
3
4
5
6
public class DogTest {
public static void main(String[] args) {
Dog dog = new Dog(); // 打印出 "这是一个无参数的构造方法"
dog.eat();
}
}

栗子2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Dog {
int size;
String name;

// 构造方法 注意:这里被注释了
// public Dog() {
// System.out.printLn("这是一个无参数的构造方法");
// }

public Dog(int size) {
System.out.printLn("这是一个有参数的构造方法" + 10);
}

public void eat() {
System.out.printLn("这是一个吃的方法");
}
}
1
2
3
4
5
6
public class DogTest {
public static void main(String[] args) {
Dog dog1 = new Dog(); // 报错了,没有提供无参数的构造方法
Dog dog2 = new Dog(10); // "这是一个有参数的构造方法10"
}
}

栗子3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Dog {
int size;
String name;

// 构造方法1
public Dog() {
System.out.printLn("这是一个无参数的构造方法");
}
// 构造方法2
public Dog(int size) {
System.out.printLn("这是一个有参数的构造方法" + 10);
}

public void eat() {
System.out.printLn("这是一个吃的方法");
}
}
1
2
3
4
5
6
public class DogTest {
public static void main(String[] args) {
Dog dog1 = new Dog(); // "这是一个无参数的构造方法"
Dog dog2 = new Dog(10); // "这是一个有参数的构造方法10"
}
}

当两个方法名字相同时,这就是方法的重载
功能相当的方法,名字相同,调用起来更方便,使用不同的方法,就好象在调用同一个方法一样

封装特性

栗子1:

1
2
3
public class Dog {
int size;
}
1
2
3
4
5
6
7
8
public class DogTest {
public static void main(String[] args) {
Dog dog1 = new Dog();
dog1.size = 100;
dog1.size = 200;
dog1.size = -200; // 目前可以任意赋值,当我们想限制的时候就需要封装了
}
}

栗子2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Dog {
privite int size;

public int getSize () {
return size;
}
public void setSize (int data) {
if (data < 0) {
System.out.print('数值不合法');
return;
}
size = data;
}
}
1
2
3
4
5
6
7
8
9
10
public class DogTest {
public static void main(String[] args) {
Dog dog1 = new Dog();
dog1.size = 100; // 报错
dog1.getSize(); // 0
dog1.setSize(10);
dog1.getSize(); // 10
dog1.setSize(-10); // 输出 '数值不合法'
}
}

this

栗子1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Dog {
privite int size;

public int getSize () {
return size;
}
public void setSize (int age) {
if (age < 0) {
System.out.print('数值不合法');
return;
}
this.size = age; // TODO: 注意这里的变动
}
}
1
2
3
4
5
6
7
8
9
10
public class DogTest {
public static void main(String[] args) {
Dog dog1 = new Dog();
dog1.size = 100; // 报错
dog1.getSize(); // 0
dog1.setSize(10);
dog1.getSize(); // 10
dog1.setSize(-10); // 输出 '数值不合法'
}
}

继承

继承的术语

1
2
3
public class B extend A {
类体
}

A类:父类、基类、超类、superClass
B类:子类、派生类、subClass

那些数据可以被继承?

  • 私有的数据不可以被继承
  • 构造方法不可以被继承
  • 其他的都可以被继承
1
2
3
4
5
6
7
8
public class Animal {
privite void test() {
}
public int age;
public void move() {
System.out.print("可以移动");
}
}
1
2
3
public class Dog extend Animal {

}
1
2
3
4
5
6
7
8
9
10
11
public class Cat extend Animal {
privite void test() { // 报错,私有属性不能重写
}
public int age; // 报错,属性不能重写
public void move() { // 只有方法支持重写/覆盖
System.out.print("猫在移动");
}
public void jump() {
System.out.print("猫在跳动");
}
}
1
2
3
4
5
6
7
8
9
public class Test01 {
public static void main (String[] args) {
Animal animal = new Animal();
Dog dog = new Dog();
Cat cat = new Cat();
dog.move(); // "可以移动"
cat.move(); // "猫在移动"
}
}

类的多态

相关概念:

  • 向上转型:子类 —> 父类
  • 向下转型:父类 —> 子类

无论是向上转型,还是向下转型,两个类之间必须存在继承关系,否则编译报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Test01 {
public static void main (String[] args) {
Animal animal = new Animal();
Dog dog = new Dog();
Cat cat = new Cat();
dog.move(); // "可以移动"
cat.move(); // "猫在移动"

Animal cat2 = new Cat(); // 采用多态机制写代码
cat2.move(); // "猫在移动"
cat2.jump(); // 报错,jvm 会在 Animal.class 去找 jump 方法

Cat cat3 = (Cat)cat2; // 强制转换
cat3.jump(); // "猫在跳动"
}
}

作用、应用:

1
2
3
4
5
public class Dog {
public void eat() {
System.out.print("小狗吃");
}
}
1
2
3
4
5
public class Cat {
public void eat() {
System.out.print("小猫吃");
}
}
1
2
3
4
5
6
7
8
9
public class Human {
public void feed(Cat c) {
c.eat();
}

public void feed(Dog d) {
d.eat();
}
}
1
2
3
4
5
6
7
8
9
10
public class Test01 {
public static void main (String[] args) {
Human man = new Human();
Dog dog= new Dog();
Cat cat = new Cat();

man.feed(dog); // "小狗吃"
man.feed(cat); // "小猫吃"
}
}

但是如果有很多的小动物的话,那么 Human 就要写很多的 feed 方法,非常不利于维护
所以我们需要利于多态,这里来创造一个基类 Pet

1
2
3
4
public class Pet {
public void eat() {
}
}
1
2
3
4
5
public class Dog extends Pet {
public void eat() {
System.out.print("小狗吃");
}
}
1
2
3
4
5
public class Cat extends Pet {
public void eat() {
System.out.print("小猫吃");
}
}
1
2
3
4
5
public class Human {
public void feed(Pet p) {
p.eat();
}
}
1
2
3
4
5
6
7
8
9
10
public class Test01 {
public static void main (String[] args) {
Human man = new Human();
Dog dog= new Dog();
Cat cat = new Cat();

man.feed(dog); // "小狗吃"
man.feed(cat); // "小猫吃"
}
}

抽象类和接口

抽象类无法被示例化,天生是用来被继承的

1
2
3
public abstract class People {

}
1
2
3
4
5
public class Test01 {
public static void main(String[] args) {
People p = new People(); // 报错,抽象类不能被继承
}
}

抽象方法

  • 没有方法体的方法叫做抽象方法
  • 语法结构:[其他访问修饰符] abstract 返回值数据类型 方法名(参数列表)
  • 特点:1. 没有方法体,以分号结尾。2.有 abstract 修饰。
  • 抽象方法必须存在于抽象类中
1
2
3
4
5
6
7
8
pubilc abstract class People {
// 定义一个抽象方法
public abstract void work();
// 定义一个普通方法
public void soSome() {

}
}
1
2
3
pubilc class Human extends People {
// 报错,抽象方法 work 没有实现
}

接口

  • 接口是特殊的抽象类,也是一种引用数据类型
  • 接口是全抽象的,抽象类是半抽象的
  • 语法结构:[访问修饰符] interface 接口名 {}
  • 接口支持多继承,一个接口可以继承多个接口
1
2
3
pubilc interface A {

}
1
2
3
pubilc interface B {

}
1
2
3
pubilc interface C extends A,B {

}
  • 接口中只包含两部分内容:1. 常量。2.抽象方法。
  • 接口中所有的元素都是 public 修饰的。
  • 类和类之间存在继承关系,类和接口之间存在实现关系。
1
2
3
4
5
6
7
8
9
pubilc interface C extends A,B {
// 定义一个常量
public static final double PI = 3.14;
// 简写
double PI = 3.14;
// 定义一个方法
void doSome();

}
1
2
3
4
pubilc class MyC implements C {
public void doSome(){
}
}