一、包
1. 如果需要使用 java.util 中的其他类, 可以使用import java.util.*
import java.util.*;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
2. 使用 import static 可以导入包中的静态的方法和字段
3. 将类放到包中
基本规则:
- 在文件的最上方加上一个 package 语句指定该代码在哪个包中。
- 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.bit.demo1 )。
- 包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码。
- 如果一个类没有 package 语句, 则该类被放到一个默认包中。
4. 包的访问权限控制
我们已经了解了类中的 public 和 private. private 中的成员只能被类的内部使用.
如果某个成员不包含 public 和 private 关键字, 此时这个成员可以在包内部的其他类使用, 但是不能在包外部的类使用.
二、继承(is - a 语义).
// Animal.java
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Cat.java
class Cat {
public String name;
public Cat(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Bird.java
class Bird {
public String name;
public Bird(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
public void fly() {
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿");
}
}
Java 单继承的语言
面试问题: 继承到底继承了父类的什么东西?
答: 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
1. 语法规则
class 子类 extends 父类 {
}
- 使用 extends 指定父类。
- Java 中一个子类只能继承一个父类 (而C++/Python等语言支持多继承)。
- 子类会继承父类的所有 public 的字段和字段。
- 对于父类的 private 的字段和方法,子类中是无法访问的。
- 子类的实例中, 也包含着父类的实例,可以使用super关键字得到父类实例的引用。
- 只写独有的数据 不用写父类中已有的。
2. protected关键字
如果设为private,子类不能访问
protected 体现封装性,但子类也可以访问
- 对于类的调用者来说,protected修饰的字段和方法是不能访问的。
- 对于类的子类和同一个包的其他类来说,protected修饰的字段和方法是可以访问的。
- private: 类内部能访问, 类外部不能访问。
- 默认default(也叫包访问权限): 类内部能访问, 同一个包中的类可以访问, 其他类不能访问。
- protected: 类内部能访问,子类和同一个包中的类可以访问,其他类不能访问。
- public: 类的内部和类的调用者都能访问。
final int a = 10;
a = 20; // 编译出错
final 关键字也能修饰类, 此时表示被修饰的类就不能被继承
final public class Animal {
...
}
public class Bird extends Animal {
...
}
// 编译出错
Error:(3, 27) java: 无法从最终com.bit.Animal进行继承
final关键字的功能是限制类被继承
三、组合(has - a 语义)
四、多态
1.向上转型(子类对象转成父类对象)
父类引用子类的对象 —> 叫向上转型
Bird bird = new Bird("圆圆");
Animal bird2 = bird;
// 或者写成下面的方式
Animal bird2 = new Bird("圆圆");
- 赋值 子类给父类
- 参数
- 返回类型
Animal animal = new Bird("圆圆");
animal.eat("谷子");
// 执行结果:圆圆正在吃谷子
注意事项 :对于 Animal animal = new Bird("圆圆") 这样的代码:
- 编译器检查有哪些方法存在, 看的是 Animal 这个类型。
- 执行时究竟执行父类的方法还是子类的方法, 看的是 Bird 这个类型。
// (Bird) 表示强制类型转换
Bird bird = (Bird)animal;
bird.fly();
// 执行结果:圆圆正在飞
instanceof 可以判定一个引用是否是某个类的实例. 如果是, 则返回 true. 这时再进行向下转型就比较安全了.
Animal animal = new Cat("小猫");
if (animal instanceof Bird) {
Bird bird = (Bird)animal;
bird.fly();
}
3.super 关键字(放第一行)
4.动态绑定(运行时绑定)(多态的一个过程)
在 Java 中, 调用某个类的方法, 究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引 用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为 动态绑定.
条件
- 先要向上转型——>父类的引用,引用子类的对象
- 父类和子类都有同名的覆盖方法(重写)
特殊:Class对象在方法区
5.方法重写
重写/覆盖/覆写(Override):
- 函数名相同
- 参数列表相同
- 返回值也要相同
- 静态的方法和构造方法不能被重写
- 子类的访问修饰限定符一定要大于等于父类的访问修饰限定符(父类的方法不能是私有的)
重载(Overload):
- 函数名相同
- 参数列表不同(类型,个数)
- 返回值不做要求
重写、重载的区别:
6.理解多态
多态顾名思义,就是“一个引用,能表现出多种不同的形态”
代码层次理解:多态存在的前提:
- 要有继承关系
- 子类要重写父类的方法
- 父类引用指向子类对象
- 运行时绑定(动态绑定)
class Shape {
public void draw() {
// 啥都不用干
}
}
class Cycle extends Shape {
@Override
public void draw() {
System.out.println("○");
}
}
class Rect extends Shape {
@Override
public void draw() {
System.out.println("□");
}
}
class Flower extends Shape {
@Override
public void draw() {
System.out.println("♣");
}
}
/我是分割线//
// Test.java
public class Test {
public static void main(String[] args) {
Shape shape1 = new Flower();
Shape shape2 = new Cycle();
Shape shape3 = new Rect();
drawMap(shape1);
drawMap(shape2);
drawMap(shape3);
}
// 打印单个图形
public static void drawShape(Shape shape) {
shape.draw();
}
}
五、抽象类
abstract class Shape {
abstract public void draw();
}
1.包含抽象方法的类 叫做抽象类
2.抽象类和普通类,最大的区别:包含抽象方法;
3.抽象类不能被实例化 ,不能被new;
4.抽象类存在的最大意义:肯定要被继承;
5.抽象类一旦被继承,就要重写抽象方法;
6.如果一个类一旦继承了抽象类,那么如果不重写抽象类的方法,那么当前类,需要设计为抽象类;
7.抽象类不能final,抽象方法不能private;
8.抽象类中可以包含其他非抽象方法, 也可以包含字段. 这个非抽象方法和普通方法的规则都是一样的, 可以被重写, 也可以被子类直接调用。
六、接口
接口中包含的方法都是抽象方法, 字段只能包含静态常量。
interface IShape {
void draw();
}
class Cycle implements IShape {
@Override
public void draw() {
System.out.println("○");
}
}
- 使用interface定义一个接口
- 定义的方法默认是:public abstract;
- 定义的成员变量默认是:public static final;
- 尽量简洁——>不用加上面所列的内容;
- 类和接口的关系——>实现:implements;此时表达的含义不再是 "扩展", 而是 "实现"
- 实现了接口,一定要重写抽象方法;
- 在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例.
- 接口不能单独被实例化.
1.实现多个接口
class Duck extends Animal implements IRunning, ISwimming, IFlying {
public Duck(String name) {
super(name);
}
@Override
public void fly() {
System.out.println(this.name + "正在用翅膀飞");
}
@Override
public void run() {
System.out.println(this.name + "正在用两条腿跑");
}
@Override
public void swim() {
System.out.println(this.name + "正在漂在水上");
}
}
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}
面试问题:
什么是多态?
重写和重载的区别?
super,this区别?
抽象类和接口的区别?
访问修饰限定符了解吗?
应用:
多态 抽象类 接口