Java:面向对象编程

目录

继承:

protected: 

super: 

Final: 

多态: 

override: 

抽象类: 

接口: 


封装:

使用private关键字将属性封装(这个属性只在当前类的内部可见,对外部隐藏)

方法的重载:

 在同一个类中,定义了若干方法名称相同,参数列表不同,返回值无关的一组方法

继承:

   当类和类之间满足一个类 is a 另外一个类一定是存在继承关系.

   Bird is an Animal

   Duck is an Animal

此时Bird和Duck都是Animal的子类

 当一个类继承了另外一个类,另一个类中所有的属性和方法子类就天然具备了.

Java中使用extends表示类的继承

public class Dog extends Animal

 满足继承关系的类之间一定是逻辑垂直的关系

继承规则:

   a. 要使用继承,必须要满足is a的关系

   b. 一个子类只能继承一个父类(单继承)

   c.子类会继承父类所有属性和方法,显示继承(public属性和方法可以直接使用)

      隐式继承(private属性和方法),子类也继承了这个属性和方法,但无法直接使用(父类提供的        get/set方法).

protected: 

 protected权限:当前类的内部/同包不同类/子类中可以使用

private<default<protected<public

super: 

修饰属性:表示直接从父类中寻找同名属性

修饰方法:表示直接从父类中寻找同名方法

public class B {
    public B() {
        System.out.println("1.B的构造方法");
    }

    {
        System.out.println("2.B的构造代码快");
    }
    static {
        System.out.println("3.B的静态快");
    }
}
public class D extends B{
    public D() {
        System.out.println("4.D的构造方法");
    }

    {
        System.out.println("5.D的构造快");
    }

    static {
        System.out.println("6.D的静态快");
    }

    public static void main(String[] args) {
        System.out.println("7.main开始");
        new D();
        new D();
        System.out.println("8.main结束");
    }
}

 当 new D(); 无参构造产生子类对象之前先默认调用父类的构造方法,产生父类对象,然后才会   执行子类的构造方法

 要产生一个子类对象先默认产生父类对象!!!

结果: 

3.B的静态快
6.D的静态快
7.main开始
2.B的构造代码快
1.B的构造方法
5.D的构造快
4.D的构造方法
2.B的构造代码快
1.B的构造方法
5.D的构造快
4.D的构造方法
8.main结束
System.out.println(this.name); //直接当前类中寻找同名属性,若不存在,在向上找
System.out.println(super.name);//直接从父类中寻找同名属性,若不存在,在向上找

  父类中定义了private name;就无权访问

super修饰构造方法:

public class Animal {
    public String name;
   
    //Animal默认的无参构造就不再产生

    public Animal(String name) {
        this.name = name;
    }
}
public class Dog extends Animal{
    
//显示调用父类的有参构造
//要想产生父类的对象就要调用父类的构造方法
    public Dog() {
        super("name");
    }

    public static void main(String[] args) {
             new Dog();
    }
}

 super(); //直接父类的无参构造,可写可以不写

 若父类中不存在无参构造,则子类构造方法的首行必须使用super(有参构造)
 在一个构造方法中无法显示使用this()和super()同时出现


Final: 

 修饰属性:表示属性值不能修改,常量

 修饰类表示这个类无法继承


多态: 

 一个引用可以表现出多种行为/特征

向上转型:最大的意义在于参数统一化,降低使用者的使用难度!!

父类名称 父类引用 = new 子类对象();

     Animal animal = new Dog();

向上转型发生在有继承关系的类之间

不一定时之间子类,也可以是孙子类

最主要的多态:继承+方法重写!!!

//有了向上转型之后最顶端的父类引用就可以指代所有的子类对象
//当Animal有新的子类时,就非常容易扩展
fun(new Dog());
fun(new Duck());

//fun中animal局部变量的引用调用eat方法时,当传入不同的对象,表现出来不同的eat,
  这就是多态
public static void fun(Animal animal){
        animal.eat();  
    }

override: 

方法的重写(override):发生在有继承的类之间,子类定义了和父类除权限不同,其他全都相同的                                     方法(返回值可以是向上转型的返回值) ,这一组方法称为方法的重写

       Animal animal1 = new Dog();
       Animal animal2 = new Duck();
       Animal animal3 = new Bird();

        fun(animal1);
        fun(animal2);
        fun(animal3);
        
        public static void fun(Animal animal){
            animal.eat();
        }

这三个类都重写了eat方法 ,到底调用了谁的方法哪?

 答: 看new的是谁调用的就是谁的eat方法.

若子类没有重写这个方法,则就近匹配规则,谁近就调用谁的

当发生重写时,子类的权限要>=父类权限 

 父类方法使用private,子类方法使用public是否可以?

 答:不可以,private不包含在内

 java中有一个@override

使用这个注解在重写方法之前,帮助校验重写方法是否符合规则

能否重写staitic方法?

答:不能, 多态的本质就是调用了不同的子类对象,使这些子类对象所属的类覆写相应的方法

     才能表现出不同的行为,static和对象无关!!!

 


向上转型的应用:

 1.方法传参使用最多

 2.方法的返回值 

pulic static Animal test(){
      Dog dog = new Dog();
       return dog;
    }

public class B {

    public B() {
        fun();
    }
    public void fun(){
        System.out.println("b.fun");
    }
}
public class D extends B{
    private int num = 10;

//这时还没有执行D的构造方法!! D的所有属性都是默认值
    public void fun(){
        System.out.println("D.fun,num = "+ num);
    }

         //调用D的无参构造,这时存在继承,优先调用B的构造方法产生父类对象
    public static void main(String[] args) {
        D d = new D();
    }
}

结果:D.fun,num = 0 

向下转型: 

当要使用子类中独有的属性和方法时就要向下转型!

 类名称 引用名称 = new 类实例();

引用名称.方法名称();

能通过"."访问的方法,类名称说了算

能访问的方法必须在类中定义过,编译器会先在类中查找是否包含此方法

至于这个方法表现出来是哪个类的样子,实例所在方法说了算

public class Animal {

    public void eat(){
        System.out.println("Animal的eat方法");
    }


}
public class Dog extends Animal{

    @Override
    public void eat() {
        System.out.println("Dog类的eat方法");
    }

    public void play(){
        System.out.println("Dog类独有的play方法");
    }

 }

    public static void main(String[] args) {
//要发生向下转型,首先要向上转型
        Animal animal = new Dog();
        animal.eat();
//要想使用Dog类中独有的play方法,就要向下转型
        Dog dog = (Dog) animal;
        dog.play();
}
//毫无关系的两个类之间无法强转

Animal animal = new Animal();

Dog dog = (Dog)Animal;//error
       //此时这个animal2引用和Dog类毫无关系
        Animal animal2 = new Animal();
        //要发生向下转型首先父类引用就是通过该类向上转型产生的
        Dog dog2 = (Dog) animal2;
        dog2.play();

instanceof:

向下转型时会有风险,类型转换异常!!

引用名称 instanceof 类 => 返回布尔值,表示该引用指向的本质不是该类对象

        Animal animal1 = new Animal();
        Animal animal2 = new Dog();
        if(animal1 instanceof Dog){
            Dog dog = (Dog) animal1;
            System.out.println("animal1"+"转型成功");
        }else {
            System.out.println("animal1转型失败");
        }
        if (animal2 instanceof Dog){
            Dog dog = (Dog) animal2;
            System.out.println("animal2"+"转型成功");
        }else {
            System.out.println("animal2"+"转型失败");
        }

结果:  animal1转型失败
          animal2转型成功 


public class Person {

    public void fun(){
        this.test(); //表示此时在父类中
    }
   
         //test方法是private权限子类无法覆写
    private void test() {
        System.out.println("1.Person的test方法");
    }
}
public class Student extends Person{
   //子类并没有覆写父类方法,就是一个普通方法
    public void test(){
        System.out.println("2.Student的test方法");
    }
}
public class Test01 {
    public static void main(String[] args) {
        new Student().fun();
    }
}

  Person  test() {
        System.out.println("1.Person的test方法");
        return new person();
    }


   //子类使用student作为返回值,父类使用Person作为返回值是可以的,Student is a Person
 public Student test(){
        System.out.println("2.Student的test方法");
        return new Student();
    }

抽象类: 

抽象类,只是比普通类多了一些抽象方法.

抽象类虽然没法直接实例化对象,但依然要满足 is a 原则!!!

Java中定义抽象类或者抽象方法使用abstract关键字

 1.抽象方法所在的类必须使用abstract声明为抽象类

    抽象方法:使用abstract关键字声明,没有方法体的方法,称为抽象方法

//抽象方法所在的类,必须为抽象类
public abstract class Sharp {
    
    //抽象方法没有方法体,到子类实现
    public abstract void print();
}

 Java中,没有方法体的方法就是抽象方法?

  答:error. 本地方法也没有方法体,不是抽象方法

 本地方法,不是抽象方法,这个方法的具体实现由JVM实现JVM是C++写的

本地方法指的是调用了C++中的同名方法

 2.抽象类,不能实例化对象,哪怕类中一个抽象方法没有

   只能通过子类向上转型为抽象父类

public abstract class Sharp {
    public abstract void print();
}
public class Cycle extends Sharp{
    @Override
    public void print() {
        System.out.println("haha");
    }

    public static void main(String[] args) {
        Sharp sharp = new Cycle();
        sharp.print();
    }
}

 3.子类继承了抽象类,子类就必须覆写抽象父类中的所有抽象方法(子类是普通类),只能单继承

4.  抽象类不能实例化对象,但是也存在构造方法,子类在实例化时,仍然遵从继承的规则,先调用父类的构造方法,然后调用子类的构造方法!!!

abstract class BaseTest {

    public BaseTest() {
        this.print();
    }
    abstract void print();
}

 class Fun extends BaseTest {
    private int num = 10;
    @Override
    void print() {
        System.out.println("num = "+num);
    }

    public static void main(String[] args) {
       new Fun();
    }
}

 结果: num = 0

当一个类既可以使用抽象类也可以使用接口,优先使用接口!!!  

接口: 

接口使用的两种场景:

  1.接口表示具有某种能力/行为,子类实现接口时不是 is a 而是具备这种行为或能力(多实现)

     "游泳" ->person满足,Dog也满足,Duck也满足

  2.接口表示一种规范或标准

     "USB接口",5G标准

 接口中只有全局常量和抽象方法

 接口使用关键字interface声明接口,子类使用implements实现接口

//USB接口表示一种规范
public interface USB {
    //插入
    void plugIn();
    //工作
    void work();
}

Mouse和Keyboard都属于USB的子类 

//子类实现接口必须覆写所有抽象方法
public class Mouse implements USB{
    @Override
    public void plugIn() {
        System.out.println("鼠标驱动加载中");
    }

    @Override
    public void work() {
        System.out.println("鼠标正在工作中");
    }
}
public class KeyBoard implements USB{
    @Override
    public void plugIn() {
        System.out.println("键盘驱动安装中~~");
    }

    @Override
    public void work() {
        System.out.println("键盘工作中~~");
    }
}

 只要这个设备满足USB接口,都可以插入到电脑识别,兼容所有的USB子类对象.

 fun(Mouse mouse) 这个接口只能插入鼠标,键盘都不可以,这两个类毫无关系

public class Computer {

    public static void main(String[] args) {
        Computer computer = new Computer();
        KeyBoard keyBoard = new KeyBoard();
        Mouse mouse = new Mouse();
        computer.fun(keyBoard);
        computer.fun(mouse);
    }
    public void fun(USB usb){
        usb.plugIn();
        usb.work();
    }
}
//子类可以实现多个父接口,父接口里的抽象方法都要覆写
public class KeyBoard implements USB,IRun{
    @Override
    public void plugIn() {
        System.out.println("键盘驱动安装中~~");
    }

    @Override
    public void work() {
        System.out.println("键盘工作中~~");
    }
}

接口中只有全局常量和抽象方法,因此接口中 public abstract 可以省略

只保留最核心的返回值,参数列表和方法名即可 

public interface USB {
    //插入
    void plugIn();
    //工作
    void work();
}
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值