JAVA学习笔记09-面向对象编程-1

一、包

包是类的一种组织方式,主要目的是保证类的唯一性。(可以把包理解为装着各种类的文件夹)

1、导入包中的类:
示例:我们在没有导入Java工具包的时候直接使用Scanner类时,发现编译器会报错!
在这里插入图片描述
我们可以使用如下方法来使用Java工具包中的Scanner类
1-1、Java.util.[className]

public class TestDemo {
    public static void main(String[] args) {
        java.util.Scanner scanner = new java.util.Scanner(System.in);

    }
}

1-2、使用import 导入Java中的工具类:
导入Scanner示例
代码如下:

import java.util.Scanner; 	//使用import导入工具包中的Scanner类;
public class TestDemo {
	public static void main(String[] args) {
   	 	Scanner scanner = new Scanner(System.in);
	}
}

使用 * 导入所有工具类示例
代码如下:

import java.util.*;		//使用import导入工具包中的所有类;
public class TestDemo {
	public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
    }
}

有时我们直接使用import来导入类的时候会出现冲突的情况,因为图中的这个Date类在util 包和 sql 包中都存在,此时编译器无法知道我们用的是哪一个包中的Date类。
在这里插入图片描述
此时我们需要显示的指定要使用的类。
代码示例如下:

import java.util.*;
import java.sql.*;
public class TestDemo {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();

    }
}

1-3、静态导入
使用import可以导入包中静态的方法和字段

import static java.lang.System.*;
public class TestDemo {
    public static void main(String[] args) {
        out.println("heloworld");

    }
}

2、把类放到包中
2-1、创建包的方法:
在这里插入图片描述
在弹出的对话框中输入包名(包名一般为小写且不要出现中文)
在这里插入图片描述
2-2、在包中新建一个类:
在新建的包名右键>>New>>JavaClass新建一个类,然后输入类名即可。
在这里插入图片描述
此时在新建的类的上方会显示包名
在这里插入图片描述
3、包的访问权限:
3-1、访问修饰限定符(public private protected default(包访问修饰符))
1、被public修饰的在任何地方都可以进行访问;
2、被protected修饰的可以在同一包中的同一类或者不同类,以及不同包中的子类被进行访问;
3、被private修饰的只能在同一包中的同一个类中进行访问;
4、default修饰的可以在同一包中进行访问;

二、继承

1.语法规则

class 子类 extend 父类{

}

子类也叫作派生类;
父类也称为 超类或者基类;

  • Java中一个子类只可以继承一个父类(单继承);
  • 子类会继承所有父类中被public修饰的方法和字段;
  • 父类中被private修饰的字段和方法不会被子类继承;
  • 子类也能够继承父类中的实例,可以使用super关键字来调用父类中实例的引用。

代码示例1:
public修饰父类成员变量


    //定义一个Animal类;
    class Animal {
        //类的成员变量;
        public String name;

        //类中的方法:
        public void eat(String food) {
            System.out.println(name + "正在吃" + food);
        }

    }

    //定义一个继承Animal类的Cat类;
    class Cat extends Animal{
        public void run(){
            System.out.println(name + "奔跑");
        }
    }

    //定义一个继承Animal类的Bird类;
    class Bird extends Animal{
        public void fly(){
            System.out.println(name + "在天上飞");
        }
    }
 public class TestDemo {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.name = "米米";
        cat.eat("猫粮");
        cat.run();
        System.out.println("======================");
        Bird bird = new Bird();
        bird.name = "八歌";
        bird.eat("虫子");
        bird.fly();
    }
}   

代码执行结果:
在这里插入图片描述
代码示例2:
成员变量不添加修饰符时默认为包访问权限

public class TestDemo0422 {
    public static void main(String[] args) {
        Cat cat = new Cat("米米"); //实例化一个Cat类;
        cat.imfor(2,"公");  //调用Cat类的方法;
        System.out.println("===================");
        cat.eat("猫粮");  //调用父类方法;
        System.out.println("====================");
        cat.run();  //调用Cat类中的run方法

    }
}

    class Animal {
        //Animal类中的成员变量
        String name ;
        String sex;
        int age;

        //构造函数
        public Animal(String name) {
            this.name = name;
        }

        //类方法
        public void eat(String food) {
            System.out.println(this.name + "正在吃" + food);
        }
    }

    //创建一个继承Animal类的不带任何成员变量的Cat类
    class Cat extends Animal {
        //重写父类构造方法
        public Cat(String name) {
            //使用super关键字调用父类的name成员变量
            super(name);
        }
        //Cat类方法
        public void run() {
            System.out.println(this.name + "正在奔跑");
        }
        public void imfor(int age, String sex) {
            this.age = age;     //在Cat类中并没有定义age和sex成员变量,此处是Cat类继承了了父类中的age和sex成员变量
            this.sex = sex;
            System.out.println(this.name + "是一只" + this.age + "岁的" + sex + "猫");
        }
    }

在这里插入图片描述
使用private修饰父类的成员变量,子类就不能进行调用
在这里插入图片描述
运行结果:
在这里插入图片描述

如果使用public来修饰父类的成员变量,就会违背封装的初衷,此时我们使用protected关键字(访问权限:同一包中的类内部、子类、不同类;不同包中的子类能进行访问)来对父类成员变量进行修饰

class Animal1 {
        protected String name;
        protected int age;

        //构造函数
        public Animal1(String name) {
            this.name = name;
        }
    }

    class Dog extends Animal1 {
        public Dog (String name) {
            super(name);
        }
        public void show () {
            System.out.println("狗的名字是" + this.name);
        }
    }
public static void main(String[] args) {
        Dog dog = new Dog("花花");
        dog.show();
    }

运行结果:
在这里插入图片描述
在同一包中建立不同的类,用protecte修饰Animal类的成员变量在同一包中来实现访问
在这里插入图片描述
Animal类

public class Animal {
    protected String name;
    protected String sex;
    protected int age;

    public Animal(String name) {
        System.out.println("父类的构造方法被调用了");
        this.name = name;
    }
    public void eat(String food) {
        System.out.println("父类的eat方法被调用了");
        System.out.println(this.name + "正在吃" + food);
    }
}

Cat类

public class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }
    public void run(String leg) {
        System.out.println("正在用" + leg + "奔跑");
    }
}

Bird 类

public class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }
    public void fly(String wing) {
        System.out.println(this.name + "正在用" + wing + "飞");
    }
}

Test类

public class Test {
    public static void main(String[] args) {
        Cat cat = new Cat("米米");
        cat.eat("猫粮");
        cat.run("四条腿");
        System.out.println("===================");
        Bird bird = new Bird("八歌");
        bird.eat("虫子");
        bird.fly("翅膀");
    }
}

运行结果:
在这里插入图片描述

定义一个Orange类继承Cat类
在这里插入图片描述

public class OrangeCat extends Cat {
	//调用父类Cat类的构造函数
    public OrangeCat(String name) {
    //调用父类的成员变量
        super(name);
    }
    //创建一个Orange类的方法
    public void sleep() {
        System.out.println(this.name + "正在睡觉");
    }
}
public static void main(String[] args) {
        OrangeCat orangeCat = new OrangeCat("橘子");
        //调用Cat类的run方法
        orangeCat.run("四条腿");
        System.out.println("=======================");
        //调用父类的eat方法
        orangeCat.eat("猫粮");
        System.out.println("=======================");
        orangeCat.sleep();
    }

在这里插入图片描述
final关键字
被final修饰的变量是常量,不能被修改
被final修饰的类不能够够被继承
//使用final修饰Animal类

final public class Animal {
    protected String name;
    protected String sex;
    protected int age;

    public Animal(String name) {
        System.out.println("父类的构造方法被调用了");
        this.name = name;
    }
    public void eat(String food) {
        System.out.println("父类的eat方法被调用了");
        System.out.println(this.name + "正在吃" + food);
    }
}

此时我们运行Test会出现异常,Animal类无法被继承
在这里插入图片描述

2、多态

1、向上转型
1-1、直接赋值
代码示例:
向上转型可以理解为动物这个类别中包含狗这种子类别;

public class Test0422 {
    public static void main(String[] args) {
        //向上转型,animal引用指向了一个子类Dog的实例
        Animal animal = new Dog("旺财");
        //Dog(对象)的引用(dog)调用了父类中的eat方法
        animal.eat("狗粮");
    }
}

    class Animal{
        public String name;

        public Animal(String name) {
            System.out.println("父类的构造方法执行了");
            this.name = name;
        }
        public void eat(String food) {
            System.out.println("父类的eat()方法执行了");
            System.out.println(name + "正在吃" + food);
        }
    }

    class Dog extends Animal {
        public Dog(String name) {
            super(name);
        }
        public void bark() {
            System.out.println(this.name = "汪汪");
        }
    }

在这里插入图片描述

向上转型时引用属于父类的类型,而在父类中并没有包括子类的特有方法,所以不能调用子类的特有方法(例如 不是所有的动物都会飞)
在这里插入图片描述
在这里插入图片描述
1-2 传值向上转型

 public static void main(String[] args) {
      Dog dog = new Dog("花花"); //dog引用指向Dog
      func(dog);  //传入参数dog到func中,传参后,func()的参数指向dog指向的对象名叫花花的 狗(对象)
    }
    public static void func(Animal animal) {
        System.out.println(animal.name + "正在晒太阳");
    }

在这里插入图片描述
1-3、方法返回

public static void main(String[] args) {
  Animal animal = func();  //接收引用dog指向的对象
    System.out.println("这个动物的名字叫做" + animal.name);
}
public static Dog func() {
    Dog dog = new Dog("花花");
    return dog;
}

在这里插入图片描述

2、动态绑定

当父类和子类中存在同名的方法,在进行调用时要区分出引用指向的是谁的对象。如果引用指向的是父类的对象,则调用父类的方法。指向子类对象就调用子类的方法。这个过程是程序运行时决定的而不是编译时决定的,所以称为动态绑定。
代码示例:

public class Animal {
    protected String name;
    protected String sex;
    protected int age;

    public Animal(String name) {
        System.out.println("======父类的构造方法被调用了======");
        this.name = name;
    }
    public void eat(String food) {
        System.out.println("======父类的eat方法被调用了======");
        System.out.println(this.name + "正在吃" + food);
    }
}
public static void main(String[] args) {
        //bird1这个引用指向Animal的对象
        Animal bird1 = new Animal("八歌");
        bird1.eat("鸟食");
        //bird2这个引用指向Bird的对象
        Animal bird2 = new Bird("黄鹂");
        bird2.eat("虫子");
    }

在这里插入图片描述
3、方法的重写
在动态绑定的例子中,子类实现和父类同名的方法,且参数类型、数量都一致,这就是方法的重写(也称为覆写、覆盖)override。

  1. 重写与重载是不一样的;
  2. 普通方法可以重写,static修饰的静态方和final修饰的方法不能重写;
  3. 重写的子类方法的权限不能低于父类方法的权限,同时,父类方法的访问修饰限定符不能是private;
  4. 重写的子类的方法的返回值不一定和父类的相同,但是建议一般要相同。

4、多态

作为类的创建者编写的部分:
定义一个父类Shape

public class Shape {
    public void printShape() {
    //啥都不用干
    }
}

定义多个继承父类Shape的子类

public class Cycle extends Shape {
    //重写父类方法
    @Override
    public void printShape() {
        System.out.println("○○○○○○○○○○");
    }
}
public class Flower extends Shape {
    //重写父类方法
    @Override
    public void printShape() {
        System.out.println("♣♣♣♣♣♣♣♣♣♣♣");
    }
}
public class Hurts extends Shape {
        //重写父类方法
        @Override
        public void printShape() {
            System.out.println("♥♥♥♥♥♥♥♥♥♥♥");
        }
}
public class Dalmons extends Shape {
    //重写父类方法
    @Override
    public void printShape() {
        System.out.println("◇◇◇◇◇◇◇◇◇◇◇");
    }
}

//以下部分作为类的调用者编写

public class Test2 {
   public static void main(String[] args) {
	      public static void main(String[] args) {
	        Shape shape0 = new Cycle();
	        Shape shape1 = new Dalmons();
	        Shape shape2 = new Flower();
	        Shape shape3 = new Hurts();
	        disPlayShape(shape0);
	        disPlayShape(shape1);
	        disPlayShape(shape2);
	        disPlayShape(shape3);
	      }
    //类的调用者创建一个打印方法
	    public static void disPlayShape(Shape shape) {
	        shape.disPlay();
	    }
   }
}   

运行结果:
在这里插入图片描述
对于类的调用者来说,在编写disPlay打印方法的时候并不知道shape引用指向的是哪一个对象,此时shape调用printShape方法进行打印时可能会有多种情况,这具体要看shape引用指向的是哪一个类的实例,这就是多态。

三、抽象类

1、包含抽象方法的类就是抽象类,被abstract修饰的方法称为抽象方法。
语法规则:

public abstract class Shape {
    
     public abstract void disPlay();
}

在dispaly方法前面加上一个abstract关键字,表示这是一个抽象方法,抽象方法没有方法体(也就是{}),不能执行具体代码。包含抽象方法的类Shape也需要用abstract关键字来修饰表示这是一个抽象类。

  1. 抽象类不能直接实例化,抽象类就是为了被继承而存在的。普通类可以被实例化,也可以被继承;
  2. 抽象类和普通类都可以被继承、向上转型、动态绑定;
  3. 抽象类当中的方法一定要被子类重写,而普通类被继承后,方法可以不被重写;
  4. 抽象类继承了一个抽象类,可以不重写父类的方法。如果这个抽象类再被一个普通类继承,那么在这个普通类中一定要重写父类的方法;
  5. 抽象类中的方法不能是private来修饰,因为会被无法继承。抽象类中除了包含抽象方法还可以包含普通方法和字段,这个普通方法可以被子类继承、重写或者直接调用。

抽象类的代码示例:

 //类的编写者实现抽象类Shape及其子类等 
public abstract class Shape {
    //被abstract修饰的抽象方法
    public abstract void disPlay();
     //创建一个普通的方法
    public void func() {
        System.out.println("抽象类中的普通方法");
    }
}

//类的调用者实现:
 public static void main(String[] args) {
        Shape shape0 = new Cycle();
        Shape shape1 = new Dalmons();
        Shape shape2 = new Flower();
        Shape shape3 = new Hurts();
        disPlayShape(shape0);
        disPlayShape(shape1);
        disPlayShape(shape2);
        disPlayShape(shape3);
        disPlay(shape0);
    }
    
    //创建一个打印方法
    public static void disPlayShape(Shape shape) {
        shape.disPlay();
    }
    public static void disPlay(Shape shape) {
        shape.func();
    }

运行结果:
在这里插入图片描述

四、接口

接口是抽象类的更进一步,使用interface关键字来定义接口。
代码示例:

public interface IShape {
    int n = 10;
    void display();
}
  • 接口的名称以大写字母 I 开头,命名一般用形容词性;
  • 接口不能被单独实例化;
  • 接口中的方法默认一定是抽象方法,所以可以省略abstract;
  • 接口中的方法默认一定是public,所以可以省略public;
  • 接口中也可以有字段,但是一定要是静态常量,static和final可以省略,编程规范一般约定接口中的字段不加任何修饰符,保持代码的简洁性;
  • 接口可以扩展接口(extends);
  • JDK1.8以上版本,接口中可以定义被default修饰的普通方法;同样可以被类调用;

类使用implements来“继承接口” ,此时表达的含义不是扩展,而是实现
代码示例1:

public class Cycle implements IShape {
    @Override
    public void display() {

    }
}
  • 在Java中只支持单继承,也就是一个class只可以extends一个父类,但是可以implements多个接口;一个类可以继承另一个类同时实现多个接口;
    代码示例:
//创建一个Animal 类
public class Animal {
    String name;
    public Animal(String name) {
        System.out.println("======父类的构造方法执行了======");
        this.name = name;
    }
}
//定义一个代表会跑的接口
public interface IRunning {
    void run() ;
}
//定义一个代表会飞的接口
public interface IFlaying {
    void fly();
}

//定义一个代表会游泳的接口
public interface ISwimming {
    void swim();
}
//创建一个Cat类继承Animal类并实现IRunning接口
public class Cat extends Animal implements IRunning {
    //重写父类构造方法
    public Cat(String name) {
        super(name);
    }
    //重写接口方法
    @Override
    public void run() {
        System.out.println(this.name + "正在奔跑");
    }
}
//定义一个Frog类继承Animal类并实现两个接口
public class Frog extends Animal implements ISwimming,IRunning {
    //重写父类构造方法
    public Frog(String name) {
        super(name);
    }
    //重写接口方法
    @Override
    public void swim() {
        System.out.println(this.name + "正在水里游来游去");
    }

    @Override
    public void run() {
        System.out.println(this.name + "正在向前跳");
    }
}
//定义一个Duck类继承Animal类并实现三个接口
public class Duck extends Animal implements ISwimming,IFlaying, IRunning {
    //重写父类构造方法
    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 + "浮在水面上");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Cat cat = new Cat("米米");
        funcRunning(cat);
        Frog frog = new Frog("王子");
        funcSwimming(frog);
        //上面两行代码也可以写成如下形式
        funcRunning(new Frog("王子"));
        funcRunning(new Duck("唐老鸭"));
        funcSwimming(new Duck("唐老鸭"));
        funcFlaying(new Duck("唐老鸭"));
    }

    //定义一个实现方法,参数为会跑的类
    public static void funcRunning (IRunning running) {
        running.run();
    }
    //定义一个实现方法参数为“会游泳的“类
    public static void funcSwimming (ISwimming swimming) {
        swimming.swim();
    }
    //定义一个实现方法,参数为会飞的
    public static void funcFlaying(IFlaying flaying) {
        flaying.fly();
    }
}

运行结果:
在这里插入图片描述

代码示例2(实现Comparable 接口中的compareTo方法):

class Student implements Comparable<Student> {
    String name;
    int score;
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

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

    @Override
    public int compareTo(Student o) {
        if (this.score > o.score) {
            return 1;
        }else if (this.score < o.score) {
            return -1;
        }else
            return 0;
    }

}

```java
import java.util.Arrays;

public class TestDemo {
    public static void main(String[] args) {
        Student[] students = new Student[]{
                new Student("赵雷", 84),
                new Student("钱电", 89),
                new Student("孙风", 79),
                new Student("李云", 94)
        };
        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
    }
}

运行结果:
在这里插入图片描述
代码示例3

总结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值