Java教程

Java基础学习笔记(五)

本文主要是介绍Java基础学习笔记(五),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

面向对象

面向对象与面向过程

  1. 面向过程
    • 处理一些较为简单的问题
    • 步骤清晰简单
  2. 面向对象
    • 适合处理复杂的问题,处理需要多人协作的问题
    • 属性+方法=类
    • 面对复杂的问题,首先将问题分类,然后对这些分类进行面向过程的思索

基本特征

封装

原则:高内聚,低耦合。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合,仅暴露少量的方法给外部使用。

属性私有:private 外部不能再调用

get/set:为private属性提供一些可以public的方法

package com.okami.oop;
//学生类
public class Student {

    //属性
    private String name;
    private int age;

    //get获得这个数据
    public String getName(){
        return this.name;
    }
    //set设置值
    public void setName(String name){
        this.name=name;
        
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age>120||age<0){
            this.age=10;
        }else{
            this.age = age;
        }
    }
}
package com.okami.oop;

public class Demo02 {
    public static void main(String[] args) {
        //类实例化后返回一个自己的对象
        //student对象是Student类的具体实例

        Student lilei = new Student();
        Student hanmeimei=new Student();

        lilei.setName("李雷");

        System.out.println(lilei.getName());
    }
}

封装的优点:

  1. 提高程序的安全性,保护数据
  2. 隐藏代码的实现细节
  3. 统一接口
  4. 增加系统可维护性

继承

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

关键字:extends 扩展的意思,子类是对父类的扩展

优先级:public>protected>default>private

特点:

  1. JAVA中只有单继承,没有多继承(一个子类只有一个父类)
  2. 继承是类与类的一种关系(还有依赖、组合、聚合等)
  3. 子类继承父类,会拥有父类的全部方法
  4. JAVA中所有的类,都默认直接或间接继承object
  5. super
    • super调用父类的构造方法,必须在构造方法的第一个
    • super只能出现在子类的方法或者构造方法中
    • super不能与this同时调用构造方法
      1. this代表调用者,super代表对父类对象的引用
      2. this没有继承也可以使用,super只有在继承条件下从可以使用
      3. this调用本类的构造,super调用父类的构造
package com.okami.oop;

public class Person {
    protected String name = "父类";
}
package com.okami.oop;

public class Teacher extends Person {
    private String name = "老师";

    public void t(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    }
}
public class App {
    public static void main(String[] args) {
        Teacher teacher=new Teacher();
        teacher.t("何老师");
    }
}
执行结果:
何老师
老师
父类
  1. 重写
    • 需要有继承关系,子类重写父类的方法
    • 重写都是方法的重写,与属性无关
    • 方法名、参数列表必须一致,方法体不同
    • 修饰符范围可以扩大但不能缩小:public>protected>default>private
    • 只与非静态有关
    • 抛出的异常范围可以缩小不能扩大
package com.okami.oop.chongxie;

public class B {
    public static void test() {
        System.out.println("B=>test()");
    }
}
package com.okami.oop.chongxie;

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

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

        //静态方法的调用只和左边,定义的数据类型有关
        A a = new A();
        a.test();

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

    }
}
执行结果:
A=>test()
B=>test()

去掉static之后

image

package com.okami.oop.chongxie;

public class B {
    public void test() {
        System.out.println("B=>test()");
    }
}
package com.okami.oop.chongxie;

public class A extends B{

    @Override //重写 有功能的注释
    public void test() {
        System.out.println("A=>test()");
    }

}
package com.okami.oop.chongxie;

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

        //方法的调用只和左边,定义的数据类型有关
        A a = new A();
        a.test();

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

    }
}
执行结果:
A=>test()
A=>test()

有static,调用类的方法,没有static时,调用对象的方法

多态

  1. 多态是方法的多态,属性没有
  2. 需要有继承关系,方法需要重写
  3. 无法重写:static、final、private
  4. 父类的引用指向子类 Father f1 = new Son();
  5. 实现动态编译,类在执行过程中决定(可扩展性),即同一方法可以根据发送对象的不同而采用不同的行为方式
  6. 一个对象的实际类型是确定的,但可以指向的引用类型有很多
  7. 由高到低可以进行强制转换,父类和子类要有联系,否则会类型转换异常ClassCastException
package com.okami.oop.duotai;

public class Person {
    public void run(){
        System.out.println("father");
    }
}
package com.okami.oop.duotai;

public class Student extends Person{
    @Override
    public void run() {
        System.out.println("son");
    }

    public void eat(){
        System.out.println("eat");
    }
}
package com.okami.oop.duotai;

public class App {
    public static void main(String[] args) {
        //一个对象的实际类型是确定的
        //new Student();
        //new Person();

        //可以指向的引用类型不确定,父类的引用指向子类
        //Student能调用的方法都是自己的或者继承父类的
        //Person父亲类,可以指向子类,但是不能调用子类独有的方法
        Student s1 = new Student();
        Person s2 = new Student();
        Object s3 = new Student();

        s1.run();//son
        s2.run();//son 子类重写了父类的方法,执行子类的方法

        s1.eat();
        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
        //s2.eat(); //不能执行
        ((Student)s2).eat(); //强制转换为子类


    }
}

instanceof

判断两个类是否有父子关系的关键字

package com.okami.oop.duotai;

public class App {
    public static void main(String[] args) {
        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object = new Student();

        System.out.println(object instanceof Student);
        System.out.println(object instanceof Person);
        System.out.println(object instanceof Object);
        System.out.println(object instanceof Teacher);
        System.out.println(object instanceof String);
    }
}
执行结果:
true
true
true
false
false

判断两个类是否具有继承关系之后,就可以进行类之间的转化

  1. 由低到高自动转换,由高到低需要强制转换,可能会丢失方法
  2. 父类引用指向子类的对象
  3. 方便方法的调用,减少重复的代码

静态static

方法调用:

image
2.
image
静态方法和类一起加载,比较早,而非静态方法在对象创建之后才存在,所以静态方法不能调用非静态方法(但当两个方法类型一致,可以互相调用)

值传递:实参和形参在内存上是相互独立的

引用传递:实参和形参在内存上指向同一个地址

静态属性、静态方法、静态代码块、静态导入包

非静态可以调静态里的所有方法,而静态方法不能调用非静态,因为static与类一起加载,比较早,且只执行一次

package com.okami.oop.duotai;

public class Demo01 {

    private static int age;//静态变量 静态属性
    private double score;//非静态变量

    //非静态方法
    public void run(){
    }
    //静态方法
    public static void go(){
    }

    public static void main(String[] args) {
        Demo01 d1 = new Demo01();

        System.out.println(Demo01.age);
        //System.out.println(Demo01.score); //非静态,不能使用类名访问
        System.out.println(d1.age);
        System.out.println(d1.score);

        new Demo01().run(); //必须new
        Demo01.go();
        go();
    }
}

静态代码块

package com.okami.oop;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

public class Demo05 {
    //2 可以用来赋初始值
    {
        System.out.println("匿名代码块");
    }
    //1 仅执行一次
    static {
        System.out.println("静态代码块");
    }
    //3
    public Demo05(){
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Demo05 d5 = new Demo05();
        System.out.println("=============================");
        Demo05 d6 = new Demo05();
    }
}
执行结果:
静态代码块
匿名代码块
构造方法
=============================
匿名代码块
构造方法

静态导入包

package com.okami.oop;

public class Demo06 {
    public static void main(String[] args) {
        System.out.println(Math.random());
    }
}
package com.okami.oop;

import static java.lang.Math.random;
import static java.lang.Math.PI;

public class Demo06 {
    public static void main(String[] args) {
        System.out.println(random());
        System.out.println(PI);
    }
}

构造器

类中的构造器也称构造方法,具有以下特点:

  1. 必须和类的名字相同
  2. 没有返回类型,void也不能用
  3. 分无参构造和有参构造,一个类即使什么都不写,也会存在一个方法,一旦定义了有参构造,若还想用无参构造,必须显示定义
package com.okami.oop;

public class Person {
    String name;
    //无参构造,默认
    public Person() {
    }
    //有参构造,重载
    public Person(String name) {
        this.name = name;  //第一个name当前类,第二个name传入的值
    }
}
package com.okami.oop;

public class Demo03 {
    public static void main(String[] args) {
        Person person=new Person("okami");
        System.out.println(person.name);
    }
}

内存情况

package com.okami.oop;

public class Pet {
    public String name;
    public int age;

    public void shout(){
        System.out.println("叫");
    }
}
package com.okami.oop;

public class Application {
    public static void main(String[] args) {
        Pet dog=new Pet();
        dog.name="旺财";
        dog.age=2;
        dog.shout();

        Pet cat=new Pet();
        cat.name="小黑";
        cat.age=1;
        cat.shout();
    }
}

image

堆里的方法区,堆放具体创建的对象,栈里是方法和一些变量的引用

面向对象编程

OOP

本质:以类的方式组织代码,以对象的形式封装数据。

特征:封装、继承、多态

类与对象:JAVA中先有类后有对象,类是对象的模板

package com.okami.oop;

//class 定义一个类
public class Dome01 {
    //main方法
    public static void main(String[] args) {

    }
    /*
    修饰符 返回值类型 方法名(...){
        (方法体)
        return 返回值:
    }
     */
    public String sayHello(){
        return "hello,world";
    }

    public void hello(){
        return;
    }

    public int max(int a,int b){
        return a>b ? a : b; //三元运算符
    }
}

类与对象的创建

package com.okami.oop;
//学生类
public class Student {

    //属性
    String name;
    int age;

    //方法
    public void study(){
        System.out.println(this.name+"认真学习");
    }
}
package com.okami.oop;

public class Demo02 {
    public static void main(String[] args) {
        //类实例化后返回一个自己的对象
        //student对象是Student类的具体实例

        Student lilei = new Student();
        Student hanmeimei=new Student();

        lilei.name="李雷";
        lilei.age=23;
        hanmeimei.name="韩梅梅";
        hanmeimei.age=22;

        System.out.println(lilei.name+" "+lilei.age);
        System.out.println(hanmeimei.name+" "+hanmeimei.age);
    }
}

使用new关键字创建对象:分配内存空间、默认初始化、调用构造器

抽象类

package com.okami.oop.chouxiang;

//抽象类的所有方法,都由继承它的子类来实现,除非它的子类也是抽象类
public class A extends Action {
    @Override
    public void doSomething() {

    }
}

特点:

  1. 使用abstract修饰符
  2. 不能new这个抽象类,只能靠子类去实现它:约束
  3. 一旦有抽象方法,类一定是抽象类;但抽象类可以有普通方法
  4. 抽象类也有构造器
  5. 增强代码的可扩展性

接口

类是单继承,但是接口可以多继承

  • 普通类:具体实现
  • 抽象类:具体实现和规范
  • 接口:只有规范,无法写方法。专业的约束,约束和实现分离:面向接口编程。接口的本质是契约
  • 声明类的关键字是class,声明接口的关键字是interface
package com.okami.oop;

//interface 定义的关键字,接口都需要有实现类
public interface Action {
    //属性默认为常量 public static final,一般不在接口中定义常量
    int AGE=99;
    //接口中的所有定义都是抽象的public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}
package com.okami.oop;

public interface TimeService {
    void timer();
}
package com.okami.oop;

//关键字implements
//实现接口的类,需要重写接口中的方法
//实现多继承
public class ActiveImpl implements Action,TimeService{
    @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 timer() {

    }
}

总结:

  1. 约束
  2. 定义一些方法,让不同的人实现
  3. 默认方法 public abstract
  4. 默认常量 public static final
  5. 接口中没有构造方法,所有接口不能被直接实例化
  6. implements可以实现多个接口,并且必须要重写接口中的方法

内部类

内部类就是在一个类的内部再定义一个类。在A类中定义一个B类,那么B类相对于A类就是内部类,A类相对于B类来说就是外部类。

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类
package com.okami.oop.Demo10;

public class Outer {
    private int id=10;
    public void out(){
        System.out.println("这是外部类的方法");
    }

    public class Inner{  //变为static类,id就拿不到了,因为这里会先加载
        public void in(){
            System.out.println("这是内部类的方法");
        }

        //内部类获得外部类的私有属性
        public void getID(){
            System.out.println(id);
        }
        
       //局部内部类
        public void method(){
            class In{
                public void in(){

                }
            }
        }
    }
}
package com.okami.oop;

import com.okami.oop.Demo10.Outer;

public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        //通过外部类来实现内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();
        inner.getID();
    }
}

一个JAVA类中可以有多个class类,但是只能有一个public class

package com.okami.oop.Demo10;

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

        UserService userService = new UserService(){
            @Override
            public void hello() {
                
            }
        };
    }
}


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

interface UserService{
    void hello();
}
这篇关于Java基础学习笔记(五)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!