Java 语法基础
面向对象
==面向对象有三宝:封装、继承和多态==
继承
关键字:extends 和 implements
类的继承是单一关系,也就是说,一个类只能有一个父类。
extends:用于继承基本类和抽象类;
implements:用于继承接口类。
两个对象之间的关系:==IS-A==;
对象和实例变量之间的关系:==HAS-A==;
所有的类均由object类继承而来,Object是上帝类。
extends关键字只能使用一次,因此java中是单继承
如果想要多继承的话使用接口,implements。避免***问题?(变相的多继承)
public class Apple extends Fruit implements Fruit1,Fruit2{}
接口:可以理解为完全抽象类。
HAS-A关系:
某个类A中实例化类B,就叫做A HAS B。
public class Vehicle{}
public class Speed{}
public class Van extends Vehicle{
private Speed sp;
}
在该例中,==Van IS Vehicle,Van HAS Speed==。
关键字:Override 和 Overload
Override:
*重写是两个类之间的覆盖(父类和子类)
- 对父类允许的实现方法进行重写,形参和返回值不变;
- 父类成员方法只能被它的子类重写;
- final 方法不能被重写,static方法也不能被重写,但能再次声明(?!)
- 构造函数不可被重写;
- 子类和父类在一个包中时,除了private和final方法,其他均可被重写;
- 不在一个包中,只能重写父类声明为public和protected的非final方法。
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
public void bark(){
System.out.println("狗可以吠叫");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
b.bark();
}
}
注:该方法编译失败,因为b的引用变量为Animal,而类Animal没有bark()方法。
关键字:Super
超类:调用父类被重写的方法时
super.function();
Overload:
- 重载,同一个类(==或子类==)中同名函数之间的覆盖(==不同的形参==);
- 构造函数也可被重载;
- 必须改变形参(顺序,个数,参数类型等),返回值可变可不变;
- ==被重载的方法可以改变访问修饰符==(没看懂!)
- 方法能够在同一个类或者在一个==子类==中被重载!
==重写和重载之间的区别:==
区别点 | 重载 | 重写 |
---|---|---|
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可以修改 | 一定不能修改 |
异常 | 可以修改 | 可以减少或删除,但一定不能跑出新的过更广的异常 |
访问 | 可以修改 | 级别可降不可升 |
多态
多态定义
==多态是指同一个行为(方法)== :具有不同的表现形式或者形态的能力,也就是方法的对象的多种表现形式。
多态存在三个必要条件:继承、重写、父类引用指向子类对象(!)
父类引用指向子类对象举例:
Animal a = new Dog();
关键字:instanceof,判断对象是否属于某类
多态的执行顺序:使用多态方式调用方法时,先检查父类中是否有这个方法,没有的话直接编译错误,如果有的话,再去调用子类中的同名方法(重写?)
我的理解:学生和老师都是人,引用变量设置为人类型,但学生和老师是不同的人(IS-A结构,父子类),每个人在课堂上有不同的表现,所以,调用人的上课方法,老师和学生就会有不同的表现。
public class Test {
public static void main(String[] args) {
//因为父类Animal中没有work()方法,所以不能调用多态特性,show()方法中需要做类型判断和转化
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
//此时,使用的是多态特性
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 catchMouse
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
执行以上程序,输出结果为:
吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠
虚方法(虚函数)
虚函数是实现多态的一种手段,在设计模式中用处较大。
- 函数加final修饰变为非虚函数;
- 抽象函数是纯虚函数;
- 编译阶段,JVM会找引用变量的方法,执行阶段,JVM使用的是实际对象的方法,这个过程称为虚方法调用;
- 编译找的父类的方法,执行的是子类的方法,这个机制保证了复写的方法能在实际运行的时候被执行;
抽象
概念:面向对象认为,所有对象都是通过类来描述的,但并不是所有类都能描述为对象,如果一个类没有足够的信息完整的表示一个对象的话,这样的类就是抽象类。
==特征:有类没对象==
抽象类
- 关键字:abstract
- 不能实例化;
- 可以有构造函数、成员变量和成员方法等元素;
- 必须被继承才能使用(==这是和静态类的主要区别==);
public abstract Person(){}
抽象方法
- 关键字:abstract
public abstract void absTest();
//抽象类中没有函数体,定义函数形参和返回值之后直接加分号。
- 抽象方法的实现由所继承的子类完成,且必须复写;
- 如果一个类中包含有抽象方法,则这个类必须是抽象类;
- 任何子类继承父类之后,必须将抽象方法全部复写,如果子类也是抽象类的话就可以不复写。
封装
概念:一种将抽象性函式接口的实现细节包装、隐藏起来的方法。(说人话:我不管你的方法咋实现的,只要能用就行!)==这也是一种安全机制==
常见的封装:getter()、setter(),必须通过固定的通道来获取对象的成员变量。
接口
关键字:interface
interface interTest [extends className]{
//声明变量:static|final
//抽象方法
}
接口和类的描述很相似,但是!类描述对象的属性和行为,接口则包含类需要实现的方法(行为),并不考虑如何实现,这点比较像抽象方法;
接口就是相当于确定一个==系统规范==,形参,返回值,含有的方法等;
和抽象类一样,普通类继承的接口需要复写所有方法,抽象类可以实现接口的部分方法;接口无法被实例化,但可以被实现(相当于实例化对象,需要实现所有方法)。
问题:使用接口而不使用抽象类的原因?
答:为了解决***的问题
问题:接口和纯抽象类的区别?
答:??
接口特性:
- 接口是隐式的抽象,声明接口,不需要再使用abstract关键字;
- 接口中的方法也是隐式抽象的,同样不需要abstract关键字;
- 接口的方法都是公有的。
接口和类的区别:
- 接口不能用于实例化对象;
- 接口不是被继承,而是被实现,因为它自身不包含描述状态和行为的信息;
- 接口没有构造函数;
- 一个类只能继承一个类,但是能实现多个接口;
- 接口中所有方法必须是==抽象方法==;
- 接口不能包含成员变量,但可以包含静态变量(static)和常量(final)
- 问题:static变量和final变量的区别:final不可变;但是static变量对类生效,类的所有对象共享变量;
- 接口的存在主要是为了实现==多继承==。
接口之间是可以被相互继承的
接口之间,类与接口之间的继承使用:extends
类实现接口方法的同时,也需要实现接口的“父接口”的所有方法:
// 文件名: Sports.java
public interface Sports
{
public void setHomeTeam(String name);
public void setVisitingTeam(String name);
}
// 文件名: Football.java
public interface Football extends Sports
{
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endOfQuarter(int quarter);
}
//实现接口Football的时候,需要实现5个方法。
划重点时刻:如何用接口实现多继承?
(接口:未完待续)
包
关键字:package
主要作用:
区别命名空间(namespace);
==权限==:限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
采用属性目录结构存储方式;
把功能相似的类和接口组织在同一个包中,方便类的查找和使用;
package pkg1.pkg2.pkg3;
public class Something{...}
包的命名规范:全部小写,避免与类和接口名冲突;
关键字:import
获取使用某些包的使用权限;在.java源文件中,import语句应该在package语句之后,类声明之前。
- 包名成为类名的一部分,例: java.lang.XXX ;
- 包名必须与编译出的字节码所在的路径结构相吻合,(相当于指定一个相对路径)