面向对象编程

一.包(包(package) 是组织类的一种方式,使用包的主要目的是保证类的唯一性)

1.用package声明我们自己写的包,用import导入系统包

2.java几个常见的系统包:

(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编程开发包

3.包访问控制权限(默认权限default):在同一个包中可进行访问

二.继承:达到代码重用的目的

class Animal{
    protected String name;
    protected int age;
    public Animal(){

    }
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(name+" Animal eat!");
    }

}
class Cat extends Animal{
    public Cat(){

    }
    public Cat(String name,int age){
        super(name,age);
    }
}
class Bird extends Animal{
    public Bird(){

    }
    public Bird(String name,int age){
        super(name,age);
    }
    public void fly(){
        System.out.println(name+" Bird fly!");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Animal animal=new Cat("xiaocat",3);//向上转型
        animal.eat();
        Animal animal1=new Bird("xiaobird",1);
        animal1.eat();
    }
}

在这个例子中

1.Animal作为父类(基类,超类),Cat和Bird作为子类(派生类),关系为extends,class子类 extends 父类{}

2.在java中是单继承,即一个子类只能继承一个父类

3.final修饰的类不能被继承 final public class A{}

4.被private修饰的类可以被继承,但不能被访问(private在类外不能访问)

5.子类不能继承父类的构造方法

6.在构造子类的构造方法时,要先帮助父类进行构造(在子类构造方法中调用父类的构造方法,super();)

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

三.多态(一个引用表现出多种不同形态)

//==============类的实现者=================
class Shape{
    public void draw(){

    }
}
class Reat extends Shape{
    @Override
    public void draw(){
        System.out.println("♦");
    }
}
class Cycle extends Shape{
    @Override
    public void draw(){
        System.out.println("●");
    }
}
class Trangle extends Shape{
    @Override
    public void draw(){
        System.out.println("△");
    }
}
//============类的调用者====================
public class TestDemo {
    public static void drawMap(Shape shape){
        shape.draw();
    }
    public static void main(String[] args) {
        Shape reat=new Reat();
        Shape cycle=new Cycle();
        Shape trangle=new Trangle();
        drawMap(reat);
        drawMap(cycle);
        drawMap(trangle);
    }
}

 

1.多态的前提:向上转型(将子类转成父类),运行时绑定(动态绑定)

向上转型的时机:直接赋值(Shape reat=new Reat(););方法传参;方法返回。向上转型时 只能访问自己有的,不能访问子类特有属性

动态绑定:在 Java 中, 调用某个类的方法, 究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引
用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为 动态绑定

2.方法重写/覆写/覆盖(override):子类实现父类的同名方法, 并且参数的类型和个数完全相同

普通方法可以重写, static 修饰的静态方法不能重写.重写中子类的方法的访问权限不能低于父类的方法访问权限

3.多态的好处:1.类的调用者对类的使用成本降低  2.降低代码的圈复杂度(分支循环语句)3.可扩展能力更强

4.向下转型(父类转成子类)

1.需要强制转换 2.使用if(A instanceof B)判定 A本质上是否是B的实例

class Animal1 {
    protected String name;
    public Animal1(String name) {
        this.name = name;
    }
    public void eat(String food) {
        System.out.println("我是一只小动物");
        System.out.println(this.name + "正在吃" + food);
    }
}

class Bird1 extends Animal1 {
    public Bird1(String name) {
        super(name);
    }

    public void eat(String food) {
        System.out.println("我是一只小鸟");
        System.out.println(this.name + "正在吃" + food);
    }

    public void fly() {
        System.out.println(this.name + "正在飞");
    }
}
class Cat1 extends Animal1{
    public Cat1(String name){
        super(name);
    }
    public void eat(String food) {
        System.out.println("我是一只小猫");
        System.out.println(this.name + "正在吃" + food);
    }
}
public class TestDemo1 {
    public static void main(String[] args) {


        Animal1 animal = new Bird1("圆圆");
        animal.eat("谷子");
        //向下转型 强制转换
        Bird1 bird=(Bird1)animal;
        bird.fly();
        //java.lang.ClassCastException: demo1.Cat1 cannot be cast to demo1.Bird1
        //animal 本质上引用的是一个 Cat 对象, 是不能转成 Bird 对象的. 运行时就会抛出异常.
        //所以, 为了让向下转型更安全, 我们可以先判定一下看看 animal 本质上是不是一个 Bird 实例, 再来转换
        //instanceof 可以判定一个引用是否是某个类的实例. 如果是, 则返回 true. 这时再进行向下转型就比较安全了.
        Animal1 animal1 = new Cat1("小猫");
        if(animal1 instanceof Bird1){
            Bird1 bird1 = (Bird1)animal1;
            bird1.fly();
        }
    }
}

5.super关键字(代表父类对象的引用):

1) 使用了 super 来调用父类的构造器

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

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

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);
}
}
 

四.抽象类 (没有实际工作的方法, 我们可以把它设计成一个 抽象方法(abstract method), 包含抽象方法的类我们称为 抽象类(abstract class)

注意 :

1.抽象类不能进行实例化new

2.抽象方法不能是private的

3.抽象类中可以包含其他的非抽象方法, 也可以包含字段. 这个非抽象方法和普通方法的规则都是一样的, 可以被重写,也可以被子类直接调用

作用:

抽象类存在的最大意义就是为了被继承

abstract class Shape{
abstract public void draw();
}
class Reat extends Shape {
    @Override
    public void draw(){
        System.out.println("♦");
    }
}
class Cycle extends Shape {
    @Override
    public void draw(){
        System.out.println("●");
    }
}
class Trangle extends Shape {
    @Override
    public void draw(){
        System.out.println("△");
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        //Shape shape=new Shape();// 错误:shape是抽象类,不能实例化
        Shape shape=new Reat();
    }
}

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

使用 interface 定义一个接口
接口中的方法一定是抽象方法, 因此可以省略 abstract
接口中的方法一定是 public, 因此可以省略 public
使用 implements 继承接口. 此时表达的含义不再是 "扩展", 而是 "实现"
在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例.
接口不能单独被实例化

class Animal{
    public String name;
    public Animal(){
    }
    public Animal(String name){
        this.name=name;
    }
}
interface IFlying{
     void fly();
}
interface ISwimming{
    void swim();
}
interface IRunning{
    void run();
}
class Dog extends Animal implements IRunning{
    public Dog(String name){
        super(name);
    }
    @Override
    public void run(){
        System.out.println(name+" 跑");
    }
}
class Frog extends Animal implements IRunning,ISwimming{
    public Frog(String name){
        super(name);
    }
    @Override
    public void run(){
        System.out.println(name+" 跑");
    }
    @Override
    public void swim(){
        System.out.println(name+" 游");
    }
}
class Duck extends Animal implements ISwimming,IRunning,IFlying{

    public Duck() {
    }

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

    @Override
    public void fly() {
        System.out.println(name+" 飞");
    }

    @Override
    public void swim() {
        System.out.println(name+" 游");
    }

    @Override
    public void run() {
        System.out.println(name+" 跑");
    }
}
public class TestDemo5 {
    public static void main(String[] args) {
        Animal dog=new Dog("dog");
        Animal frog=new Frog("frog");
        Animal duck=new Duck("duck");
    }
}

常见的几个接口

1.排序:comparable接口(用在类的内部):需要实现compareTo方法

class Student implements Comparable<Student>{
    private String name;
    private int score;
    public Student(){

    }
    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) {
        return this.score-o.score;
    }
}
public class TestDemo5{
    public static void main(String[] args) {
        Student[] student=new Student[3];
        student[0]=new Student("张三", 95);
        student[1]=new Student("李四", 88);
        student[2]=new Student("王五", 97);
        System.out.println(Arrays.toString(student));
        //java.lang.ClassCastException: Student cannot be cast to java.lang.Comparable
        System.out.println("=============排序==============");
        Arrays.sort(student);
        System.out.println(Arrays.toString(student));
    }
}

2.排序:Comparator接口(用在类外):需要实现compare方法

class scoreComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.score-o2.score;
    }
}
class nameComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
class Student{
    public String name;
    public int score;
    public Student(){

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}
public class TestDemo5{
    public static void main(String[] args) {
        Student[] student=new Student[3];
        student[0]=new Student("张三", 95);
        student[1]=new Student("李四", 88);
        student[2]=new Student("王五", 97);
        System.out.println(Arrays.toString(student));
        System.out.println("=============根据分数排序==============");
        scoreComparator scoreComparator=new scoreComparator();
        Arrays.sort(student,scoreComparator);
        System.out.println(Arrays.toString(student));
        System.out.println("=============根据姓名排序==============");
        nameComparator nameComparator=new nameComparator();
        Arrays.sort(student,nameComparator);
        System.out.println(Arrays.toString(student));
    }
}

3.拷贝:Cloneable接口(空接口/标记接口),需要实现clone方法

class Money implements Cloneable{
    public double money=6.66;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{//Cloneable是一个空接口(标记接口)
    //产生一个副本
    public String name;
    public Money m=new Money();
    public Person(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person person1=(Person)super.clone();
        person1.m=(Money)this.m.clone();
        return person1;
        //return super.clone();
    }
}
public class TestDemo5{
    public static void main(String[] args) throws CloneNotSupportedException{
     Person person=new Person("ZZZ");
     Person person1=(Person)person.clone();
        System.out.println(person.name);
        System.out.println(person1.name);
        System.out.println("=========修改name==========");
        person1.name="abc";
        System.out.println(person.name);
        System.out.println(person1.name);
        System.out.println("===========================");
        System.out.println(person.m.money);
        System.out.println(person1.m.money);
        System.out.println("=========修改m.money==========");
        //money是引用
        person1.m.money=8.88;
        System.out.println(person.m.money);
        System.out.println(person1.m.money);
    }
}

抽象类和接口的核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法.
 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值