包
继承
多态
抽象类
接口
Java本身就是面向对象编程的一门语言,这一块我们主要需要注意的就是包、继承、组合、多态、抽象类和接口。
包
包是组织类的一种方式,使用包的主要目的是保证类的唯一性。
import java.util.*
表示导入包下的所有类,虽然导入包下的所有类,但是不会将所有类加载。
对于import来说,不需要导入java.lang包(如String),因为编译器会自动帮忙导入。
将类放入包中的时候,包名需要尽量指定成唯一的名字,通常会用公司的域名的颠倒形式。
继承
例如:Bird是Animal,他们之间是(is - a)的关系,即“是”的关系。这种,Animal这样被继承的类,我们成为父类、基类或超类,对于Bird这样的类,我们称为子类、派生类。和现实中儿子继承父亲的财产类似,子类也会继承父类的字段和方法。
基本语法:
class 子类 extends 父类 { }
- 子类继承父类,那么构造子类的时候,需要先构造父类,构造对象只有一种方法:通过构造方法。
- 使用extends指定父类
- java中一个子类只能继承一个父类
- 子类会继承父类出构造方法外的所有东西
- 对于父类的private的字段和方法,子类中是无法访问的
- 子类的实例中,也包含父类的实例,可以使用super关键字得到父类实例的引用。
一个继承的例子~~
class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
class Bird extends Animal{
public Bird (String name) {
//使用super调用父类的构造方法,必须放在第一行。
super(name);
}
public void fly() {
System.out.println(this.name + "正在飞");
}
}
public class Test {
public static void main(String[] args) {
Bird bird = new Bird("hah");
bird.eat("虫子");
bird.fly();
}
}
输出:
hah正在吃虫子
hah正在飞
- super.data:访问父类的成员变量
- super.func():访问父类的方法
- super():访问父类的构造方法
this与super对应,可以对比其区别。
但是~如果把name改成private,此时的子类就不能访问,因为private是私有的,只能在当前类进行访问,因此引入protected关键字。对于类的调用者来说,protected修饰的字段和方法是不能访问的,对于类的子类和同一个包的其他类来说,protected修饰的字段和方法是可以访问的。
final关键字的使用方法
- final可以修饰常量,表示常量不能被修改
- final可以修饰类,表示当前类不能被继承
- final可以修饰方法,表示当前方法不能被重写
多态
- 向上转型:父类的引用,引用子类的对象
直接赋值
public class Test {
public static void main(String[] args) {
Bird bird = new Bird("hah");
Animal bird2 = bird;
bird2.eat("虫子");
bird.fly();
}
}
刚刚的代码就可以被改成上述形式
方法传参
public static void main(String[] args) {
Bird bird = new Bird("hah");
// Animal bird2 = bird;
// bird2.eat("虫子");
feed(bird);
bird.fly();
}
public static void feed(Animal animal) {
animal.eat("虫子");
}
方法返回
public static void main(String[] args) {
Animal animal = findMyAnimal();
}
public static Animal findMyAnimal() {
Bird bird = new Bird("hah");
bird.eat("虫子");
bird.fly();
return bird;
}
- 动态绑定
动态绑定的条件:
1.父类的引用,引用子类的对象(向上转型)
2.通过父类的引用,调用子类和父类重写的方法。
- 方法重写
方法名相同,参数列表相同(个数、类型)、返回值相同。(与重载区别:重载的方法名相同,参数列表不同,返回值不做要求)。
注意:
1.要重写的方法不能是private所修饰的
2.被final所修饰的方法,不能被重写
3.需要重写的方法子类的访问修饰限定符要大于等于父类的访问修饰限定符(public > protected > default > private)
- 理解多态
有了向上转型,董涛绑定,方法重写之后,我们就可以使用多态。
多态的实例!~
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 Flowers extends Shape {
@Override
public void draw() {
System.out.println("❀");
}
}
public class Test {
public static void main(String[] args) {
Shape shape1 = new Cycle();
Shape shape2 = new Rect();
Shape shape3 = new Flowers();
drawMap(shape1);
drawMap(shape2);
drawMap(shape3);
}
public static void drawMap(Shape shape) {
shape.draw();
}
}
- 向下转型
一个实例!~
class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
class Cat extends Animal {
public Cat(String name) {
super(name);
}
}
class Bird extends Animal {
public Bird(String name) {
super(name);
}
public void fly() {
System.out.println(this.name + "正在飞");
}
}
public class Test {
public static void main(String[] args) {
Animal animal = new Cat("小猫");
animal.eat("猫粮");
//如果要向下转型,一定要判断
if(animal instanceof Bird) {
Bird bird = (Bird) animal;
bird.eat("虫子");
bird.fly();
}
}
}
抽象类
语法规则:
//抽象类
abstract class Shape {
//抽象方法
abstract public void draw() ;
}
注意:
1.抽象类不能直接实例化
2.抽象类和普通类的区别就在于,多了一个抽象方法
3.如果一个普通类继承了抽象类,那么这个普通类一定要重写抽象类当中的抽象方法
4.抽象方法一定要被重写
5.如果一个类继承了抽象类,且不想重写抽象类方法,那么这个类只能是抽象类,一旦有其他类继承了这个抽象类,一定要重写这个抽象方法
6.抽象类更方便程序员检查代码
接口
接口是抽象类的更进一步,抽象类中还可以包含非抽象方法和字段,而接口中包含的方法都是抽象方法,字段只能包含静态常量。
接口:interface
注意:
1.所有的方法默认是public abstract
2.所有的成员变量一定是public static final
3.接口不可被实例化
4.类和接口的关系是implements
5.接口也是可以发生向上转型的
6.一个类可以实现多个接口
7.接口和接口之间是:interface ID extends IA,IB {},一旦有类实现了接口ID,那么这个类需要重写IA,IB,ID三个接口的抽象方法
8.接口的出现弥了java的缺陷,可以实现多继承了。
实现多个接口的例子!~
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
}
interface IFlying {
void fly();
}
interface IRuning {
void run();
}
interface ISwimming {
void swim();
}
class Cat extends Animal implements IRuning {
public Cat (String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "用腿跑");
}
}
class Duck extends Animal implements IRuning,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 + "正在游");
}
}