面向对象


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
  • 包名必须与编译出的字节码所在的路径结构相吻合,(相当于指定一个相对路径)

你可能感兴趣的:(面向对象)