面向对象编程

在这里插入图片描述

组织类的一种方式(就是一个文件夹)
· 在DOWS框里编译运行包里的TestDemo1
编译程序目录分割用\(如:javac com\bit\TestDemo1.java)
运行程序目录分割用.(如:java com.bit.TestDemo1.java)
在这里插入图片描述
· 我的TestDemo1在E:\decode\com\bit\TestDemo1里
要在decode目录下编译运行TestDemo1

package com.bit;//声明一下TestDemo1在哪个包里
public class TestDemo1 {
    public static void main(String[] args) {
        System.out.println("java");
    }
}

要在decode\com\bit目录下编译运行,不需要导入包
·包的命名:小写字母,采用公司网站倒叙
例:www.baidu.com->包名:com.baidu.www;
· 导入一个包中的类
用谁导入谁 如果编译器区分不了 只能自己指定
动态导入

import java.util.*;//导入util下所有的包
import java.util.Arrays;//导入util下的Arrays包

静态导入(不常用)

import static java.lang.System.*;
public class TestDemo1 {
    public static void main(String[] args) {
        out.println("hello");//可以直接out.println,可以让代码看起来简洁一点
    }
}

· 将类放入包中
在这里插入图片描述
查看启动jvm位置
在这里插入图片描述
· 访问权限
包访问权限:默认只能访问一个包里的内容
· 常见的包

  1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入
  2. java.lang.reflect:java 反射编程包;
  3. java.net:进行网络编程开发包。
  4. java.sql:进行数据库开发的支持包。
  5. java.util:是java提供的工具程序包。(集合类等) 非常重要
  6. java.io:I/O编程开发包。

继承

为了代码复用 -----------------is-a语义
· Java是单继承
· oop(面向对象语言)特征:继承、封装、多态
· 关键字:子类/派生类 extends 父类/基类/超类
· 子类继承父类除构造方法外所有东西,所以继承后要帮助父类进行构造(用super())
· super():调用父类构造方法必须放在第一行
super.func();调用父类方法
super.data;调用父类数据成员
· 要构造子类,必须先构造父类
🐕是一个动物
🐱是一个动物
父类:Animao

package com.src.demo1;

public class Animal {
    private String name;
    private int age;
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void eat(){
        System.out.println(this.name+"eat()");
    }
}

子类:Cat

package com.src.demo1;

public class Cat extends Animal{//Cat继承Animal
    //private String name;  //从父类继承,可省略
    //private int age;
    private String sex;
    public Cat(String name,int age,String sex){
        super(name,age);//必须放在第一行
        //this.name = name;//从父类继承不用再写
        //this.age = age;
        this.sex = sex;//sex为Cat特有的,无法省略
    }
     public void jump(){
        System.out.println(this.getName()+"jump");
    }
    /*public void eat(){
        System.out.println(this.getName()+"eat()");    //从Animal继承
    }*/
}

子类:Dog

package com.src.demo1;

public class Dog extends Animal{
    private String sex;
    public Dog(String name,int age,String sex){
        super(name,age);//必须放在第一行
        this.sex = sex;
    }
    public void dark(){
        System.out.println(this.getName()+"wangwang");
    }
}

测试类

package com.src.demo1;

public class Test {
    public static void main(String[] args) {
        Cat cat = new Cat("mimi",2,"man");
        cat.eat();
        Dog dog = new Dog("wangcai",2,"man");
        dog.dark();
    }
}

运行结果:在这里插入图片描述
· 基类只能访问自己的成员 或 方法
· final修饰的类不能被继承(密封类)

protected关键字

为了继承出现
· 各个关键字的权限
private: 类内部能访问, 类外部不能访问
默认(也叫包访问权限): 类内部能访问, 同一个包中的类可以访问, 其他类不能访问.
protected: 类内部能访问, 子类和同一个包中的类可以访问, 其他类不能访问.
public : 类内部和类的调用者都能访问

组合

表达类之间的关系,达到代码复用 -----------a part of / has a语义
· 将一个类的实例作为另外一个类的字段
例:

public class Student {
...
}
public class Teacher {
...
}
public class School {
public Student[] students;
public Teacher[] teachers;
}

多态

· 向上转型

· 简单理解:父类引用子类对象
还是动物为父类🐱和🐕为子类的代码基础上

public class TestDemo1 {
    public static void main(String[] args) {
        Animal animal = new Animal("动物",19);
        Cat cat = new Cat("mimi",2,"man");
        animal = cat;//向上转型
        animal.eat();//现在的anmimal指向Cat对象
    }
}

运行结果:在这里插入图片描述
也可以在直接写成:

public class TestDemo1 {
    public static void main(String[] args) {
        Animal animal = new Cat("mimi",2,"man");
        animal.eat();
    }
}

· 父类只可以调用父类自己的方法或者成员属性(annimal无法调用猫的jump()方法)
⭐ 假如在animal和cat类里都写入public void eat()方法,打印出来是cat中eat()方法里的内容
原因:运行时绑定(在构造方法内也可发生)------也叫做多态
javap -c查看反汇编
在这里插入图片描述invokestatic调用静态方法/静态绑定
程序在编译时确实调用的是Animal的方法,但是在运行时调用了cat的方法
· 这里Animal里的eat和cat里的eat发生了重写/覆盖
· 重写重载
重写:override 方法名相同,参数列表相同 返回值相同
范围:继承关系
限制:被覆盖的方法不能拥有比父类更严格的访问控制权限
注意事项:

  1. 方法不能是private
  2. 子类的方法权限要大于父类的方法权限
  3. 不能是静态的方法

重载:overlode 方法名相同,参数列表不同 返回值无要求
范围:一个类
限制:没有权限要求

· 向上转型发生时机

  1. 直接赋值
 Animal animal = new Cat("mimi",2,"man");
  1. 方法传参
public class TestDemo1 {
    public static void func(Animal animal){
        animal.eat();
    }
    public static void main(String[] args) {
        Cat cat = new Cat("mimi",2,"man");
        func(cat);
    }
}
  1. 方法返回
public class TestDemo1 {
    public static Animal func2(){
        Cat cat = new Cat("mimi",3,"man");
        return cat;
    }
    public static void main(String[] args) {
        Animal animal = func2();
    }
}
· 多态

· 发生多态(运行时多态)的条件

  1. 有继承关系-》父类需要引用子类对象(向上转型)
  2. 通过父类的引用调用子类和父类同名的覆盖方法

· 底层实现
在这里插入图片描述
方法表在编译期间已经形成

· 向下转型

· 简单理解:将父类通过强转赋值给子类的引用
增加一个鸟的类并继承Animal,增加方法fly()

public class Bird extends Animal{
    public String feather;

    public Bird(String name, int age, String feather) {
        super(name, age);
        this.feather = feather;
    }

    public void fly(){
        System.out.println("fly()");
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        Animal animal= new Bird("niao ",3,"black");
        animal.eat();
        Bird bird = (Bird)animal;
        bird.fly();//animale无法直接调用fly(),只能将其强转为Bird类型来调用fly()方法
    }
}

这里的animal就发生了向下转型
· 向下转型一般不建议使用

public class TestDemo1 {
    public static void main(String[] args) {
        Animal animal= new Bird("niao ",3,"black");
        animal.eat();
        Cat cat = (Cat)animal;//发生问题处
        cat.jump();
    }
}

运行结果:在这里插入图片描述
发生了类型转换异常
此处先将bird向上转型为animal,又将animal向下转型为cat,类型不匹配,故发生异常;上一个代码,先将bird向上转型为animal,又将animal向下转型为bird,类型匹配,故可以正常运行
· 即要发生向下转型,必须先进行同类型的向上转型

· super关键字

super 表示获取到父类实例的引用
· 使用:
1) 来调用父类的构造器

public Bird(String name) {
    super(name);
}

2)来调用父类的普通方法

public class Bird extends Animal {
     public Bird(String name) {
          super(name);
     }
@Override
     public void eat(String food) {
          // 修改代码, 让子调用父类的接口.
          super.eat(food);
          System.out.println("我是一只小鸟");
          System.out.println(this.name + "正在吃" + food);
     }
}

· super关键字和this关键字的区别
this:访问本类中的属性和方法
查找范围:先查找本类,若没有就调用父类
特殊:表示当前对象的引用
super:由子类访问父类中的属性和方法
查找范围:不查找本类,而直接调用父类定义
特殊:无

· 理解多态

写一些只关注父类的代码, 就能够同时兼容各种子类的情况.
· 例子:
类的实现部分:

class Shap{
    public void drow(){

    }
}
class Rect extends Shap{
    @Override
    public void drow() {
        //super.drow();
        System.out.println("♦");
    }
}class Cycle extends Shap{
    @Override
    public void drow() {
        System.out.println("⚪");
    }
}
class Triangle extends Shap{
    @Override
    public void drow() {
        System.out.println("🔺");
    }
}

类的调用部分:

public class TestDemo1 {
    public static void drawMap(Shap shap){
        shap.drow();
    }
      public static void main(String[] args) {
        Shap shap1 = new Rect();
        Shap shap2 = new Cycle();
        Shap shap3 = new Triangle();
        drawMap(shap1);
        drawMap(shap2);
        drawMap(shap3);
    }
}

drawMap()方法参数类型为 Shape (父类), 此时在该方法内部并不知道, 也不关注当前的 shape 引用指向的是哪个类型(哪个子类)的实例. 此时 shape 这个引用调用 draw 方法可能会有多种不同的表现(和 shape 对应的实例相关), 这种行为就称为多态.
· 使用多态的好处

  1. 类调用者对类的使用成本进一步降低.
    · 封装是让类的调用者不需要知道类的实现细节.
    · 多态能让类的调用者连这个类的类型是什么都不必知道, 只需要知道这个对象具有某个方法即可.
  2. 能够降低代码的 “圈复杂度”, 避免使用大量的 if - else
  3. 可扩展能力更强.

抽象类

· 包含抽象方法的类叫抽象类

abstract class Shap2{
    //abstract:抽像方法
    public abstract void draw();//没有具体实现的方法
}
public class TestDemo2 {
    public static void main(String[] args) {

    }
}

· 抽象类不能被实例化
· 抽象类当中可以有抽象方法 也可以有非抽象方法或者成员变量
· 为了被继承而产生,继承后必须重写里面的抽象方法
· 抽象类不能是私有的
· 抽象类A继承抽象类B,A可以不重写B里的抽象方法
· 抽象类A如果重写了,类C继承的话可以不进行重写;如果A没有重写,C继承A时要进行重写

接口

· 关键字interface定义
· 接口中的方法全部不能有具体实现(即都是抽象方法)

public interface IShap { 
    //int size = 10   ---》成员变量默认为public static final的
    void draw();//默认为public abstract的
}

· 接口当中的方法尽量简洁
· 接口中的成员变量默认为public static final的
· 接口不能单独被实例化
· 存在意义:被继承
· 类----实现---->接口
只要类(普通类)实现接口,那么接口当中的方法必须重写
· 只要类和接口存在实现关系,就可以发生向上转型
· 在调用的时候可以创建一个接口的引用, 对应到一个子类的实

class Rect3 implements IShap{
    @Override
    public void draw() {
        System.out.println("♦");
    }
}
class Cycle3 implements IShap{
    @Override
    public void draw() {
        System.out.println("⚪");
    }
}
public class TestDemo3 {
    public static void drawMap(IShap shap){
        shap.draw();
    }
    public static void main(String[] args) {
        IShap iShap = new Cycle3();
        IShap iShap1 = new Rect3();
        drawMap(iShap);
        drawMap(iShap1);
    }
}

· 扩展(extends) vs 实现(implements)
扩展指的是当前已经有一定的功能了, 进一步扩充功能.
实现指的是当前啥都没有, 需要从头构造出来.
· 接口可以同时实现多个;继承只能继承一个

class Rect3 implements IShap,IShap1,IShap2,...{
     ....
}

例:
一个动物类

class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
}

三个接口:

interface IFlying {
    void fly();
}
interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}

猫的类:

class Cat extends Animal implements IRunning {
    public Cat(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用四条腿跑");
    }
}

青蛙:

class Frog extends Animal implements IRunning, ISwimming {
    public Frog(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在往前跳");
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在蹬腿游泳");
    }
}

继承表达的含义是 is - a 语义, 而接口表达的含义是 具有xxx特性
· 类和接口是实现关系,接口和接口是继承关系
⭐Compearable接口
自定义类型排序时要implements Comparable< >接口,并重写其compearTo方法

import java.util.Arrays;
//自定义类型排序时要实现implements Comparable<Student>,并重写其方法
class Student implements Comparable<Student>{//Compearable接口进行排序,<要排序的类型>
    public String name;
    public int age;
    public double score;
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        //return this.age - o.age;//传进来的age和当前的age进行比较
        return this.name.compareTo(o.name);//-->对名字进行比较
    }
}
public class Test {
    public static void sort(Comparable[] comparables){//传的类型是实现Compearable接口的
        //冒泡
        for (int i = 0; i < comparables.length ; i++) {
            for (int j = 0; j < comparables.length-i-1; j++) {
                if(comparables[j].compareTo(comparables[j+1])>0){
                    Comparable tmp = comparables[j + 1];
                    comparables[j + 1] = comparables[j];
                    comparables[j] = tmp;
                }
            }
        }
    }
    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("lala",5,39);
        students[1] = new Student("bibi",9,89);
        students[2] = new Student("dodo",1,9);
        System.out.println(Arrays.toString(students));
        //Arrays.sort(students);//Arrays.sort排序时实现Compearable接口
        sort(students);
        System.out.println(Arrays.toString(students));

    }
}

⭐Cloneable接口
自定义类型克隆时要implements Cloneable接口,并重写其clone方法

class Person implements Cloneable{
    public String name;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test2 {
    public static void main1(String[] args) throws CloneNotSupportedException{
        Person person = new Person();
        person.name = "caocao";
        System.out.println(person.name);
        System.out.println("clone");
        Person person1 = (Person) person.clone();
        person1.name = "liubei";
        System.out.println(person.name);
        System.out.println(person1.name);
    }
}

加油鸭!🦆🦆🦆

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值