JAVA面向对象

发布于:2022-10-17 ⋅ 阅读:(591) ⋅ 点赞:(0)

1.包

  1.包(package) 是组织类的一种方式,使用包的主要目的是保证类的唯一性,package和import的区别在于:package是包,指类所在的包,import是引入,引入类中需要的类.

  2.如下图代码所示,导入了一个具体的类,import能导入一个具体的类,例如:import java.util.Arrays,但是不能导入一个具体的包.

  3.在import导入中我们也可以使用import java.util.*,其中*表示通配符,与C语言的#include不同,#include会将头文件中全部内容拿来使用,而JAVA是用到哪个类就使用哪个类。

  4.更建议显式的指定要导入的类名. 否则还是容易出现冲突的情况,如下图1.2所示代码。

//代码1.1
import java.util.Arrays;

public class test {
    public static void main(String[] args) {
        int[] arr={1,2,3,4,5};
        System.out.println(Arrays.toString(arr));
    }
}

//代码1.2

import java.util.*;
import java.sql.*;

public class Test {
	public static void main(String[] args) {
	// util 和 sql 中都存在一个 Date 这样的类, 此时就会出现歧义, 编译出错
	Date date = new Date();
	System.out.println(date.getTime());
}
}
// 编译出错
Error:(5, 9) java: 对Date的引用不明确
java.sql 中的类 java.sql.Date 和 java.util 中的类 java.util.Date 都匹配

1.1 包的创建

包的创建规则

  1. 在文件的最上方加上一个package语句指定该代码在哪个包
  2. 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.baidu.demo )
  3. 包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码
  4. 如果一个类没有 package 语句, 则该类被放到一个默认包中.

idea创建包的过程

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


1.2 包的访问控制权限

  我们已经了解了类中的 public 和 private. private中的成员只能被类的内部使用.
  如果某个成员不包含 public 和 private 关键字, 此时这个成员可以在包内部的其他类使用, 但是不能在包外部的类使用.
  如下图代码所示,Demo1 和 Demo2 是同一个包中.
  没有任何修饰符的权限就是包访问权限,意味着当前包的所有类都可以访问成员.

package com.bit.demo;
public class Demo1 {
	int value = 10;
}
package com.bit.demo;
public class Demo2 {
	public static void Main(String[] args) {
		Demo1 demo = new Demo1();
		System.out.println(demo.value);
	}
}
// 执行结果, 能够访问到 value 变量    -> 10

2.继承

  代码中创建的类, 主要是为了抽象现实中的一些事物(包含属性和方法).有的时候客观事物之间就存在一些关联关系, 那么在表示成类和对象的时候也会存在一定的关联.
  比如我们创建动物类,代码如下图所示:

class Animal{
    public int age;
    public String name;
    public void eat(){
        System.out.println("eat()");
    }
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
    }

}
class Dog{
	 public int age;
   	 public String name;
   	 public void eat(){
        System.out.println("eat()");
    }
}
class Bird extends Animal{
    public String wing;
    public String name;
    public void fly(){
        System.out.println("fly()");
    }
}

  在上述的代码中,我们会发现出现了许多的冗余代码,Dog,Bird和Animal存在着关联,于是我们可以把它们的共性抽象出来,使用extends关键字可以继承Animal类,达到代码重用的效果.
  Animal这样被继承的类, 我们称为父类,基类或超类, 对于像Cat和Bird这样的类, 我们称为子类,派生类.

2.1 继承的语法

class 子类 extends 父类 {

}

注意事项:

  1.使用 extends 指定父类

  2.Java 中一个子类只能继承一个父类

  3.子类会继承父类的所有 public 的字段和方法,子类在使用构造方法时,会先构造父类

  4.对于父类的 private 的字段和方法, 子类中是无法访问的

  5.子类的实例中, 也包含着父类的实例. 可以使用 super 关键字得到父类实例的引用

//使用extends后的代码

class Animal{
    public int age;
    public String name;
    public void eat(){
        System.out.println("eat()");
    }

}
class Dog{
	
}
class Bird extends Animal{
    public String wing;
    public void fly(){
        System.out.println("fly()");
   }
}

在这里插入图片描述

2.2 继承的限制

  不希望类之间的继承层次太复杂. 一般我们不希望出现超过三层的继承关系.
  如果想从语法上进行限制继承, 就可以使用 final 关键字.
  final 关键字, 修饰一个变量或者字段的时候, 表示常量不能修改.

 final int a = 10;
 a = 20; // 编译出错

final 关键字也能修饰类, 此时表示被修饰的类就不能被继承

final public class Animal {
...
}
public class Bird extends Animal {
...
}
// 编译出错
Error:java:无法进行继承

3.多态

3.1 多态的理解

多态 :通过一个引用调用同一个方法,会呈现出不同的表现

class Shape{
    public void drawMap(){
        ;
    }
}

class triangle extends Shape{
    @Override
    public void drawMap(){
        System.out.println("△");
    }
}

class circle extends Shape{
    @Override
    public void drawMap(){
        System.out.println("○");
    }
}

class star extends Shape{
    @Override
    public void drawMap() {
        System.out.println("☆");
    }
}

public class TEST{
    public static void drawMap(Shape a){
        a.draw();
    }

    public static void main(String[] args) {
        Shape shape1=new circle();
        shape1.drawMap();
        star s1=new star();
        drawMap(s1);
        triangle s2=new triangle();
        drawMap(s2);

    }
}

在这里插入图片描述
  参数类型为 Shape (父类), shape 引用指向的是不同类型的实例,shape 这个引用调用 draw 方法可能会有多种不同的表现这种行为就称为多态.

3.2 向上转型

class Animal{
    public int age;
    public String name;
    public void eat(){
        System.out.println("eat()");
    }
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
    }

}
class Dog extends Animal{
    public Dog(String name,int age) {
        super(name,age);
    	}
	}
}
public class Test {
    public static void main(String[] args) {
        Animal animal=new Dog("haha",12);
        System.out.println(animal.name);
    }
}

其中

 Animal animal=new Dog("haha",12);

  此时 animal是一个父类 (Animal) 的引用, 指向一个子类 (Dog) 的实例.父类引用引用子类对象,这种写法称为向上转型.
  向上转型发生的时机:1.直接赋值 2.方法传参 3.方法返回

public class Test {
	public static void main(String[] args) {
	Bird bird = new Bird("小鸟");
	feed(bird);
}
public static void feed(Animal animal) {
	animal.eat("谷子");
}
}
//小鸟正在吃谷子
public class Test {
	public static void main(String[] args) {
	Animal animal = findMyAnimal();
}
public static Animal findMyAnimal() {
	Bird bird = new Bird("小鸟");
	return bird;
}
}

3.3 动态绑定

当子类和父类中出现同名方法的时候, 再去调用会出现什么情况?

class Animal{
    public int age;
    public String name;
    public void eat(){
        System.out.println("eat()");
    }
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
    }

}
class Dog extends Animal{
    public Dog(String name,int age) {
        super(name,age);
    }
    public void eat(){
        System.out.println("狼吞虎咽地eat()");
    }
}
class Bird extends Animal{
    public String wing;
    public String name;
    public void fly(){
        System.out.println("fly()"+super.name+super.age);
    }
    public Bird(String name,int age,String wing) {
        super(name, age);
        this.wing = wing;
        this.name=name;
        this.age=age;
    }

}
public class Test {
    public static void main(String[] args) {
        Animal animal=new Dog("haha",12);
        animal.eat();
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.抽象类

    在刚才的打印图形例子中, 我们发现, 父类 Shape 中的 draw 方法好像并没有什么实际工作, 主要的绘制图形都是由Shape 的各种子类的 draw 方法来完成的.
    像这种没有实际工作的方法, 我们可以把它设计成一个抽象方法(abstractmethod), 包含抽象方法的类我们称为抽象类(abstract class)

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

注意事项:

  1.在 draw 方法前加上 abstract 关键字, 表示这是一个抽象方法. 同时抽象方法没有方法体(没有 { }, 不能执行具体代码).

  2.对于包含抽象方法的类, 必须加上 abstract 关键字表示这是一个抽象类.

  3.抽象类不能被实例化

  4.抽象类只能被继承

  5.抽象类里面可以包含成员变量和成员方法

  6.一个普通类继承了抽象类,需要重写抽象类的所有抽象方法

  7.抽象类不能被final修饰,抽象方法也不能被final修饰

  8.抽象类A继承了抽象类B,抽象类A可以不实现抽象类B的抽象方法

  9.结合第8点,当一个普通类C继承了抽象类A,类C需要重写抽象类A和抽象类B全部的抽象方法

abstract  class Shape{
    public abstract void draw();
}
abstract  class Shape{
    public abstract void draw();
}
abstract  class c extends Shape{
    public abstract void eat();
}

class b extends c {
    public void eat() {
        System.out.println("eat()");
    }
    public void draw(){
        System.out.println("draw()");
    }
}

5.接口

    接口是抽象类的更进一步. 抽象类中还可以包含非抽象方法, 和字段. 而接口中包含的方法都是抽象方法, 字段只能包含静态常量

interface IShape {
	void draw();
}
class Cycle implements IShape {
	@Override
	public void draw() {
	System.out.println("○");
	}
}
public class Test {
	public static void main(String[] args) {
	IShape shape = new Rect();
	shape.draw();
	}
}

注意事项:

  1.使用 interface 定义一个接口

  2.接口中的方法默认是抽象方法, 因此可以省略 abstract

  3.接口中的方法一定是 public, 因此可以省略 public

  4.使用 implements 继承接口. 此时表达的含义不再是 "扩展", 而是 "实现"

  5.接口中的成员变量,默认是public static final修饰的

  6.接口是不能通过new关键字来实例化的

  7.接口中可以用static方法,如果想要在接口中添加成员方法,可以使用default关键字

  8.当一个类实现了一个接口,就必须重写接口里的所有抽象方法.

  8.当一个类实现了一个接口,就必须重写接口里的所有抽象方法,重写抽象方式时,要在前面加上public,因为不添加默认是包修饰符,没有public的权限大.

  9.接口和接口之间可以通过extends来进行拓展,如果一个接口B通过extends拓展另一个接口C的功能,使用普通类实现接口B的同时,也会有接口C拓展的功能.

在这里插入图片描述

interface Itest {
    public void draw();

}
public class TEST{
    public static void drawf(Itest itest){
        itest.draw();
    }
    public static void main(String[] args) {
        drawf(new star());
        drawf(new star());
        drawf(new triangle());
    }
}

6.Comparable接口实现

public class Student implements Comparable {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "[" + this.name + ":" + this.score + "]";
    }

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

public class TT {
    public static void main(String[] args) {
        Student[] students = new Student[] {
                new Student("张三", 95),
                new Student("李四", 96),
                new Student("王五", 97),
                new Student("赵六", 92),
        };
        System.out.println(students[0].compareTo(students[1]));  //1
    }
}
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到