java 的基本特征

Java三大特征:封装、继承、多态

封装

高内聚,低耦合:类的内部数据数据操作自己完成,不允许外部干涉;尽量暴露少量方法给外部使用

属性私有,get/set

封装的意义:

1、提高程序的安全性,保护数据

2、隐藏代码的实现细节

3、统一接口

4、系统的可维护性增加

Student类:

package oop.Demo03;

//类
//封装一般是对于属性来的,很少封装方法
//private:私有
public class Student {
    //属性私有
    private String name;//名字
    private int id;//学号
    private char sex;//性别
    private int age;

    //提供一些可以操作这些属性的方法,提供一些public的get、set方法

    //get 获得这个数据  (驼峰命名)
    public String getName(){
        return this.name;
    }

    //set 给这个数据设置值
    public void setName(String name){
        this.name=name;

    }

    public void setAge(int age){//定义合理性
        if(age>120||age<0)
        this.age=3;
        else{
            this.age=age;
        }
    }
    public int getAge(){
        return this.age;
    }

    //学习()
    //睡觉()
}

Application类:

package oop;

import oop.Demo03.Student;

public class Application {
    public static void main(String[] args) {
        Student s1=new Student();
       // s1.name =      不再能通过.操作符直接使用这些属性

        s1.setName("张三");
        System.out.println(s1.getName());//张三

        s1.setAge(999);
        System.out.println(s1.getAge());//3
    }
}

继承

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模

  • 关键字:extends——扩展,子类(派生类)是父类的继承(基类),子类和父类之间从意义上将具有”is a“的关系

  • Java中只有单继承没有多继承,一个儿子只有一个爸爸,一个爸爸可以有多个儿子

  • 除继承以外,类与类之间的关系还有依赖、组合、聚合等

子类继承了父类就会拥有父类的全部方法!(public)

私有的东西(private)无法被继承

在java中,所有的类都默认直接或者间接地继承object类

super注意点:

super();

1、super调用父类的构造方法,必须在构造方法的第一个

2、super只能和初夏安在子类的方法或者构造方法中

3、super和this不能同时调用构造方法

super和this的区别

this("hello");

​ 代表的对象不同:

​ this:本身调用这个函数

​ super: 代表父类对象的引用

​ 前提不同:

​ this:没有继承也可以使用

​ super:只能在继承条件下才可以使用

​ 构造方法不同:

​ this():本类的构造

​ super():父类的构造

父类:

package oop.Demo04;
// 人 :父类

//public
//protected
//default 默认
//private
public class Person {

    public Person(){

        System.out.println("Person无参执行了");

    }

    protected String name="zhangsan";

    public void print(){
        System.out.println("Person");
    }
}

子类:

package oop.Demo04;

//学生 is 人 :派生类、子类
public class Student extends Person{

    public Student(){
        //隐藏代码:调用了父类的无参构造:super();
        super();//调用父类的构造器,必须在子类构造器的第一行
        //this("hello");
        System.out.println("Student无参构造执行了");
    }
    public Student(String name) {
        this.name=name;
    }

    private String name="zhangwu";

    public void print(){
        System.out.println("Student");
    }
    public void test1(){
        print();//Student
        this.print();//Student
        super.print();//Person
    }

    public void test(String name){
        System.out.println(name);//张五
        System.out.println(this.name);//zhangwu
        System.out.println(super.name);//父类中的zhangsan
    }

}

应用:

package oop;

import oop.Demo04.Person;
import oop.Demo04.Student;

public class Application {
    public static void main(String[] args) {

        Student student=new Student();
//        student.test("张五");
//        student.test1();
//        Student s1=new Student();
//        s1.say();//说了一句话
//        //System.out.println(s1.money);//报错
//        Person person=new Person();
    }
}

方法重写:(多态)

重写都是方法的重写,与属性无关

父类:

package oop.Demo04;

//重写都是方法的重写,与属性无关
public class B {

    public void test(){
        System.out.println("B=>test()");
    }
}

子类:

package oop.Demo04;

public class A extends B{
    public  void test(){
        //super.test();
        System.out.println("A=>test()");
    }
}

应用:

package oop;

import oop.Demo04.B;
import oop.Demo04.A;
public class Application {

    public static void main(String[] args) {
        //方法的调用之和左边,定义的数据类型有关
        A a = new A();
        a.test();//A

        //父类的引用(b)指向了子类(A)
        B b = new A();//子类重写了父类的方法
        b.test();//A
    }
}

结果:
java 的基本特征

静态方法和非静态方法区别很大:

如果方法改成静态的:(就不是重写了)

package oop.Demo04;

//重写都是方法的重写,与属性无关
public class B {

    public static void test(){
        System.out.println("B=>test()");
    }
}
package oop.Demo04;

public class A extends B{
    public static void test(){
        //super.test();
        System.out.println("A=>test()");
    }
}
package oop;

import oop.Demo04.B;
import oop.Demo04.A;
public class Application {

    public static void main(String[] args) {
        //方法的调用之和左边,定义的数据类型有关
        A a = new A();
        a.test();//A

        //父类的引用(b)指向了子类(A)
        B b = new A();//子类重写了父类的方法
        b.test();//B
    }
}

结果:java 的基本特征
是不是重写可以看左边蓝色圆圈箭头,是重写才有,静态方法没有,改成私有也没有:

java 的基本特征
java 的基本特征

改成私有:

java 的基本特征
java 的基本特征

总结:

​ 重写需要有继承关系,而且是子类重写父类的方法

​ 1、方法名必须相同

​ 2、参数列表必须相同(区分于重载,重载是当前方法,且参数列表不同)

​ 3、修饰符:范围可以扩大,但不能缩小 public>protected>default>private

​ 4、区分于抛出异常:范围可以被缩小,但不能扩大。 ClassNotFoundExcetion -->Excetion(大)

重写就是子类的方法和父类必须相同,方法体不同

为什么要重写:

​ 1、父类的功能,子类不一定需要,或者不一定满足

​ 快捷键:Alt+Insert : override

面向对象基础

关键字 ( instanceof )

instanceof (类型转换) 引用类型,判断一个对象是什么类型

父类:

package oop.Demo04;

public class Person {

}

子类1:

package oop.Demo04;

public class Student extends Person{

}

子类2:

package oop.Demo04;

public class Teacher extends Person{

}

应用:

package oop;
import oop.Demo04.*;

public class Application {

    public static void main(String[] args) {

        //Object>String
        //Object>Person>Teacher
        //Object>Person>Student
       Object object = new Student();

       //System.out.println(X instanceof Y);//能不能编译成功,取决于X与Y有没有父子关系!
        System.out.println(object instanceof Student);//true
        System.out.println(object instanceof Person);//true
        System.out.println(object instanceof Object);//true
        System.out.println(object instanceof Teacher);//false
        System.out.println(object instanceof String);//false
        System.out.println("================");
        Person person = new Student();
        System.out.println(person instanceof Student);//true
        System.out.println(person instanceof Person);//true
        System.out.println(person instanceof Object);//true
        System.out.println(person instanceof Teacher);//false
//        System.out.println(person instanceof String);//编译报错,平级不能比较
        System.out.println("================");
        Student student = new Student();
        System.out.println(student instanceof Student);//true
        System.out.println(student instanceof Person);//true
        System.out.println(student instanceof Object);//true
//        System.out.println(student instanceof Teacher);//编译报错,平级不能比较
    }
}

类型之间的转化:父|子

1、父类引用指向子类对象

2、把子类转换为父类(向上转型,低转高),直接转

3、把父类转换为子类(向下转型,高转低),需要强制转换

4、方便方法的调用,减少重复代码

抽象的编程思想:封装、继承、多态!抽象类:接口

父子关系和上文一样:

package oop;
import oop.Demo04.*;

public class Application {

    public static void main(String[] args) {
        //类型之间的转化:父|子

        //高                 低
        Person obj = new Student();
//        student.go();//不能执行

        //student将这个对象转换为Student类型,就可以使用Student类型的方法了
        //高转低强制转换
        Student student = (Student) obj;
        student.go();
        ((Student) obj).go();

        //子类转为父类,可能丢失自己本来的一些方法
        Student student1 = new Student();
        student1.go();
        Person person = student;//低转高直接转换

    }
}

关键字 static(静态)

对类来说静态变量在内存中只有一个,它能被类的所有实例共享

在类中,静态方法可以直接调用静态方法,但不能调用非静态方法

非静态方法可以调用静态方法里的所有东西

package oop.Demo05;

//static
public class Student {

    private static int age;//静态变量,多线程会使用
    private  double score;//非静态变量

    public void run(){
        go();//非静态方法可以调用静态方法里的所有东西
    }
    public static  void go(){

    }
    public static void main(String[] args) {
        Student s1= new Student();//对类来说静态变量在内存中只有一个,它能被类的所有实例共享

        System.out.println(Student.age);//0//静态变量推荐使用类名访问
//        System.out.println(Student.score);//无法编译,非静态字段不能这么用
        System.out.println(s1.age);//0
        System.out.println(s1.score);//0.0

        Student.go();
        go();//在类中,静态方法可以直接调用静态方法,但不能调用非静态方法
//        Student.run();//编译不成功



    }
}

静态代码块:

package oop.Demo05;

public  class Person {

    {
        //代码块(匿名代码块),作用:赋初始值
        //没有名字,无法调用,类加载一次运行一次
        System.out.println("匿名代码块");
    }

    static{
        System.out.println("静态代码块");
        //静态代码块,类一加载直接执行,永久只执行一次
    }

    public Person() {
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Person person1 = new Person();
        System.out.println("=============");
        Person person2 = new Person();
    }
}

结果:

java 的基本特征

被final修饰的类不能被继承:

public final class Person {
}

public class Student extends Person{
}

java 的基本特征

抽象类(abstract)

关键字:abstract

public abstract class Action 

抽象的抽象:约束

抽象类的所有方法,由继承了它的子类,都必须实现它的方法

抽象类的特点:

​ 1、不能new这个抽象类,只能靠子类去实现它:约束

​ 2、有抽象方法的类一定是抽象类,但抽象类里可以写普通方法

抽象类不能new,那它有构造器吗?

抽象类存在的意义是什么?

​ 比如创建游戏中的角色,每个角色非常复杂,反复创建非常麻烦,抽象共有属性,修改各自方法就行。可以节省代码,提高效率

抽象类:

package oop.Demo06;

//abstract 抽象类:类  只能单继承 extends:单继承(只能继承一个类)     接口可以实现多继承
public abstract class Action {

    //约束:有人帮我们实现
    //abstract 抽象方法,只有方法名字,没有实现
    public abstract void doSomething();

    public void hello(){
        System.out.println("hello"); 
    }

}

抽象类的子类:

package oop.Demo06;

//抽象类的所有方法,由继承了它的子类,都必须实现它的方法
public class A extends Action{

    @Override
    public void doSomething() {

    }
}

接口(interface)

普通类:只有具体实现

抽象类:具体实现和规范(抽象方法)都有!

接口:只有规范!自己无法写方法。专业的约束!约束和实现分离:面向接口编程

接口就是规范,定义的是一组规则,本质是契约

关键字:interface

public interface UserService

软件IDEA中普通类、抽象类和接口在图标上的的区别:

java 的基本特征
接口的作用:

1、是一种约束,可以定义一些方法,让不同的人实现

2、接口中的所有方法都是 public abstract,所有属性都是public static final

3、接口不能被实例化,接口不是类,接口中没有构造方法

4、类可以实现接口 关键字:implements 接口(可以实现伪多继承)

5、实现了接口的类,就需要重写接口中的所有方法

接口1:

package oop.Demo07;

//interface 定义的关键字,接口都需要有实现类
public interface UserService {
    //接口中的所有定义的方法其实都是抽象的public abstract
    public abstract void run();

    //接口中的所有定义的属性都是常量public static final(一般不会在接口里定义常量)
    public static final int age = 99;

    void add(String name);
    void  delete(String name);
    void  update(String name);
    void  query(String name);

}

接口2:

package oop.Demo07;

public interface TimeService {
    void time();
}

应用1:

package oop.Demo07;

//抽象类:extends
//类可以实现接口 关键字:implements 接口
//实现了接口的类,就需要重写接口中的方法

//多继承:利用接口实现多继承
public class UserServiceImpl implements UserService,TimeService{

    @Override
    public void run() {

    }

    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }

    @Override
    public void time() {

    }
}

内部类

在A类中定义B类,B类相对于A类就是内部类

使用:通过外部类来实例化内部类

一个java文件中可以有多个class类,但只能有一个public class

例1:

内部类:

package oop.Demo08;

public class Outer {

    private int id;

    public void out() {
        System.out.println("这是外部类的方法");
    }

    public void method(){
        class Inner2{//局部内部类,类似函数里的局部变量
            public void in(){//内部类里的方法

            }
        }
    }
    
    public  class Inner {//如果这里是public static class
        // 那下面getID就不行了,除非把id也改成static
        public void in() {
            System.out.println("这是内部类的方法");
        }

        //内部类可以 获得外部类的私有属性
        public void getID() {
            System.out.println(id);
        }

    }
}

应用:

package oop;
import oop.Demo04.*;
import oop.Demo08.Outer;

public class Application {

    public static void main(String[] args) {
        //new

        Outer outer = new Outer();

        //通过外部类来实例化内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();



    }
}

例2:

(一般不这么用)

package oop.Demo08;

public class Test {
    public static void main(String[] args) {
        Apple apple = new Apple();
        //没有名字初始化类——匿名对象的使用,不用将实例保存到变量中
        new Apple().eat();

        UserService userService = new UserService(){
            public void hello(){

            }
        };

    }
}

class Apple{
    public void eat(){
        System.out.println("1");
    }
}

interface UserService{//接口
    void hello();
}
上一篇:论文推荐-使用 Noisy Student 进行自训练可以提高 ImageNet 分类的表现


下一篇:Android小技巧:30分钟轻松入门flutter