2021-08-27面向对象基本概念(二)

面向对象基本概念(二)

数据表和简单java类的映射

设计各个类可以像数据库的数据表一样灵活的相互引用

对象的比较方式

不能直接用==

要实现内部所有属性的比较

String.equals()也是属性比较方法

属性比较方法应该在本类中完成

比如在类成员函数中实现.equals()或者.compare()这样的方法

封装属性,如被声明成private的属性可以通过内部方法引用传递访问

  1. 先进行地址判断,即本对象判断,比较栈空间地址,这样节省时间

  2. 为了防止NullPointerException的产生应该增加一个null判断

  3. 对象的属性也要进行地址数值判断,即使用==,这样如果效率更高

在本例中频繁大量的使用了this来指代当前对象.

static关键字

static关键字可以用来定义属性和方法

static定义属性

如果想把某个属性声明成公共属性可以在声明前加上static关键字

成为公共属性后,任何一个对象修改了此属性都会影响到其他对象

java中的四块常用内存区域

  1. 栈空间区域: 保存所有对象的名称, 即堆内存空间的地址

  2. 堆内存空间: 保存对象具体属性内容

  3. 全局数据区: 保存static类型属性

  4. 全局代码区: 保存所有方法定义

使用所有对象的公共代表来进行访问, 即使用类进行访问, 而不是单独实例化的对象进行访问

static对象可以由类名直接访问

所有非static对象都只能被实例化对象访问

一般描述共享性的属性, 不受实例化对象限制的属性时才会用static, 使用机会不是很高

static定义方法

定义static方法,可以用在类没有实例化对象的时候直接被调用,而不作为具体对象的成员使用

如果想定义类中的普通对象可以用static进行定义

static定义的属性和方法不受实例化对象的控制

static方法不能直接访问非static属性或方法,只能调用static属性和方法

非static方法可以访问static的属性和方法,不受任何限制

所有非static定义的结构碧素霞类明确实例化对象才会分配堆空间,之后允许被使用

static定义的结构不受实例化对象控制,可以随时访问

tips:

如果一个方法定义在主类中,并由方法中,使用public static进行声明(因为主方法也是个static方法)

如果定义在类内使用public

使用static的场景:

当类中没有属性产生,类中的方法全部用static声明

主方法

public: 对任何操作都是可见的

static: 证明此方法由类名称调用

void: 程序的开始点,没有返回值

main: 固定名称

String args[]: 控制台参数

static的实际应用
  1. 不管多少个对象都使用同一个static属性

  2. 避免实例化对象调用方法的限制

应用1:实现实例化对象的个数统计

class Book{
	private static int num =0;
	public Book(){
		numm++;
	}
}

应用2:实现属性的自动设置

比如无参的类构造方法可以让static声明的属性作为默认数据使用,不用手动输入参数

这样结果不会是null

代码块

实际开发中不建议使用代码块,他会破坏程序结构
  1. 普通代码块

    代码块写在普通方法里

    普通代码块中定义的变量是局部变量,只有代码块内能够使用

    全局变量的局部变量是一种相对概念

  2. 构造块

    代码块中卸载一个类里

    **构造块在每一次实例化对象时必被调用,且优于构造方法执行

  3. 静态块

    代码块使用static声明

    static{
    
    }
    

    非主类中有静态块时如果有多个实例化对象产生,静态块有限调用,且只调用一次,一般用于Static属性的初始化

    在主类中有静态块时,静态块优于主方法调用

    jdk1.7之前,静态块可以替换主方法使用

  4. 同步代码块

    等待多线程时

内部类

内部类是一种程序扩充

一. 一个类内部继续定义其他内部结构类

一个类除了属性和方法外,还有存在其他类的结构,并且内部类也可以定义在方法或者代码块里。

缺点:破坏了类的结构性

优点:轻松访问外部类的私有属性

如果拆成两个类,有些引用传递会非常复杂

内部类的存在是为了方便外部类的操作而存在的,非特殊情况不编写内部类

外部类可以直接调用内部类:对象.属性,来进行私有属性操作

内部类想在外部实例化:

外部类.内部类 对象 = new 外部类().new 内部类();

进行两层构造

内部类需要使用外部类中的属性,所有属性只有实例化后才会分配空间,所以在实例化内部类对象首先要实例化外部类对象

如果内部类只想被外部类访问而不想被外部调用,那么就使用private声明私有内部类

二. static内部类

不受外部类实例化对象控制的内部类,如果对内部类使用static关键字,该类就会变成"外部类",并且只能访问外部类中定义的static操作

相当于定义了一个外部类

如果想取得该种内部类的实例化

外部类.内部类 对象 = new 外部类.内部类();

不需要再实例化外部类

如果发现工程中类的前面有’’.’'考虑是不是内部类

三. 方法中定义的内部类

开发过程中,普通方法中定义内部类是最多的

从JDK1.8开始,内部类可以直接访问其所定义方法的参数和变量

JDK1.7以前,参数和变量前要用final关键字声明才能被内部类直接访问(取消和Lambda表达式有关)

链表

差不多

本章中的链表不完全

后面学完继承多态泛型后有更好的解决方案

package Linkedlist;
public class LinkedList {
    /**
     * 链表节点类
     */
    class Node {
        private String data;
        private Node next;

        /**
         * 链表节点构造方法
         * @param data
         */
        public Node(String data) {
            this.data = data;
        }

        /**
         * 构造新节点
         * @param newNode
         */
        public void addNode(Node newNode) {
            if (this.next == null){
                this.next = newNode;
            }else{
                this.next.addNode(newNode);         //递归向后查找,一直到链表尾部
            }
        }

        /**
         * 链表中查找数据
         * @param data
         * @return
         */
        public boolean containsNode(String data){
            if(data.equals(this.data)){
                return true;
            }else {
                if(this.next!=null){
                    return this.next.containsNode(data);
                }else {
                    return false;                   //递归向后查找,一直到链表尾部
                }
            }
        }

        /**
         * 按索引获取数据
         * @param index
         * @return
         */
        public String getIndex(int index) {
            if(LinkedList.this.foot++ == index){    //foot要自增以匹配数据索引
                return this.data;
            }else {
                return this.next.getIndex(index);
            }
        }

        /**
         * 此处处理一般性非根节点删除
         * @param previous
         * @param data
         */
        public void removeNode(Node previous, String data) {
            if(data.equals(this.data)){
                previous.next = this.next;          //空出当前节点,将前驱节点连接到后继节点
            }else {
                this.next.removeNode(this,data);
            }
        }

        /**
         * 将链表节点转换成数组节点
         */
        public void toArrayNode() {
            LinkedList.this.retArray[LinkedList.this.foot++]=this.data;
            if(this.next!=null){
                this.next.toArrayNode();
            }
        }

        public void setNode(int index, String data) {
            if(LinkedList.this.foot++ == index){
                this.data = data;
            }else {
                this.next.setNode(index,data);
            }
        }
    }
    /******************************************************************************/
    private Node root;          //根节点
    private int count = 0;      //计数
    private int foot = 0;       //序号标记
    private String[] retArray;  //字符数组
    /**
     * 添加节点
     * @param data
     */
    public void add(String data){
        if(data ==null){
          return;
        }
        Node newNode = new Node(data);
        if(this.root == null){
            this.root = newNode;
        }else{
            this.root.addNode(newNode);
        }
        count++;
    }

    /**
     * 返回链表长度
     * @return
     */
    public int size(){
        return count;
    }

    /**
     * 判断是否为空
     * @return
     */
    public boolean isEmpty(){
        return this.count==0;
    }

    /**
     * 封装的查找方法
     * @param data
     * @return
     */
    public boolean contains(String data){
        if(data==null||this.root==null){
            return false;
        }
        return this.root.containsNode(data);            //调用Node的查找方法
    }

    /**
     * 按索引获取数据
     * @param index
     * @return
     */
    public String get(int index){
        if(index>this.count){
            return null;
        }
        foot = 0;
        return root.getIndex(index);
    }

    public void set(int index,String data){
        if(index>this.count){
            return;
        }
        this.foot=0;
        this.root.setNode(index,data);
    }



    /**
     * 此处删除包含了删除节点是根节点的情况
     * @param data
     */
    public void remove(String data){
        if(this.contains(data)){
            if(data.equals(this.root.data)){
                this.root = this.root.next;
            }else {
                this.root.next.removeNode(this.root,data);
            }
        }
        count--;
    }

    /**
     * 将字符串链表转换成字符串数组
     * @return
     */
    public String[] toArray(){
        if(this.root==null){
            return null;
        }
        this.foot=0;
        this.retArray = new String[this.count];
        this.root.toArrayNode();
        return this.retArray;
    }

    /**
     * 清空链表
     */
    public void clear(){
        root = null;
        this.count = 0;
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值