Java 面向对象(五)

简介: 掌握对象数组的概念及用法。 掌握内部类的特点及应用,以及内部类调用方法中参数的要求。 对学习内容进行实例分析。

🔭学习内容



掌握对象数组的概念及用法。

掌握内部类的特点及应用,以及内部类调用方法中参数的要求。

对学习内容进行实例分析。


✈️目录


🔭1、对象数组

🔭2、内部类

(1)基本定义

(2)使用static定义内部类

(3)在外部访问内部类

(4)在方法中定义内部类

🔭3、实例讲解

(1)系统登录

(2)单向链表实现(一)

(3)单向链表实现(二)


🔭1、对象数组

所谓的对象数组,就是指包含了一组相关的对象的数组


说明:数组一定要先开辟空间,但是因为其是引用数据类型,所以数组中的每一个对象都是null值,则在使用时数组中的每一个对象必须分别进行实例化操作。


🌳对象数组的声明:

类[ ] 对象数组名称=new 类[数组长度] ;


🌳范例:

class Person{
    private String name;
    public Person(String name){
        this.name=name;
    }
    public String getName() {
        return this.name;
    }
}
public class Demo{
    public static void main(String[] args) {
        Person[] per=new Person[3];//声明一个对象数组,元素为默认值
        System.out.print("数组声明:");
        for(int i=0;i<per.length;i++){
            System.out.print(per[i]+"、");
        }
        per[0]=new Person("张三");
        per[1]=new Person("李四");
        per[2]=new Person("王五");
        System.out.print("\n对象实例化:");
        for(int i=0;i<per.length;i++){
            System.out.print(per[i].getName()+"、");
        }
    }
}


🌳运行结果:


数组声明:null、null、null、
对象实例化:张三、李四、王五、


🔭2、内部类

(1)基本定义

类内部也可以定义另一个类。如果在类Outer 的内部再定义一个类Inner,此时类Inner就称为内部类,而类Outer则称为外部类。

内部类可声明成public或private,当内部类声明成public或private时,对其访问的限制与成员变量和成员方法完全相同。


🌳声明格式:

标识符 class 外部类的名称{
  / /外部类的成员
  标识符 class 内部类的名称{
    / /内部类的成员
  }
}

🌳范例:定义一个内部类


class Outer{
    private String info="Hello World!";
    class Inner{
        public void print(){
            System.out.println(info);
        }
    }
    public void fun(){
        new Inner().print();
    }
}
public class Test {
    public static void main(String[] args){
        new Outer().fun();
    }
}


🌳运行结果:


Hello World!


可以发现,Inner类作为Outer类的内部类存在,并且在外部类的fun()方法之中直接实例化内部类的对象并调用方法print(),但是从以上代码中可以明显地发现,内部类的存在实际上己经破坏了一个类的基本结构,因为类是由属性及方法组成的,所以这是内部类的一个缺点


内部类的一个优点是可以方便地访问外部类中的私有属性。


(2)使用static定义内部类

使用static可以声明属性或方法,而使用static也可以声明内部类,用static声明的内部类变成了外部类,但是用static声明的内部类不能访问非static的外部类属性。


🌳范例:


class Outer{
    private static String info="Hello World!";
    static class Inner{
        public void print(){
            System.out.println(info);
        }
    }
}
public class Test {
    public static void main(String[] args){
        new Outer.Inner().print();//访问内部类
    }
}


🌳运行结果:


Hello World!


如果此时属性不是static类型,则编译时将出现错误


(3)在外部访问内部类

一个内部类除了可以通过外部类访问,也可以直接在其他类中进行调用。


🌳调用的基本格式为:


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


🌳范例:


class Outer{
    private String info="Hello World!";
    class Inner{
        public void print(){
            System.out.println(info);
        }
    }
}
public class Test {
    public static void main(String[] args){
        Outer out=new Outer();//实例化外部类对象
        Outer.Inner in=out.new Inner();//实例化内部类对象
        in.print();
    }
}


🌳运行结果:


Hello World!


首先要找到外部类的实例化对象之后,才可以通过外部类的实例化对象去实例化内部类的对象。


(4)在方法中定义内部类

在方法中定义的内部类不能直接访问方法中的参数,如果方法中的参数要想被内部类所访问,则参数前必须加上final关键字


🌳范例:


class Outer{
    private String info="Hello World!";
    public void fun(final int temp) {
        class Inner {
            public void print() {
                System.out.println("类中的属性:" + info);
                System.out.println("方法中的参数:" + temp);
            }
        }
        new Inner().print();
    }
}
public class Test {
    public static void main(String[] args){
        new Outer().fun(30);
    }
}


🌳运行结果:


类中的属性:Hello World!
方法中的参数:30


🔭3、实例讲解

(1)系统登录

模拟一个简单的用户登录程序


程序分析:使用初始化参数的方式输入用户名和密码,所以在程序运行之前首先必须判断输入的参数个数是否合法,如果不合法,则必须提示用户的程序执行错误,并退出程序,如果用户己经正确地输入了参数,则可以进行用户名及密码的验证。如果信息正确则显示“欢迎xxx光临!”,否则显示“错误的用户名及密码"


🌳代码如下:


class Check{
    public boolean validate(String name,String password){
        if(name.equals("张三") && password.equals("123")){     //验证登录信息是否正确
            return true;
        }else{
            return false;
        }
    }
}
class Operate{
    private String[] info;//用来接收输入参数
    public Operate(String[] info){
        this.info=info;
    }
    public String login(){
        Check check=new Check();
        this.isExit();
        String name=this.info[0];
        String password=this.info[1];
        String str;
        if(check.validate(name,password)){   //登录验证
            str="欢迎"+name+"光临!";
        }else{
            str="错误的用户名和密码!";
        }
        return str;
    }
    public void isExit(){
        if(this.info.length !=2){     //判断参数的个数
            System.out.println("输入的参数不正确,系统退出!");
            System.out.println("格式:java LoginDemo 用户名 密码");
            System.exit(1);
        }
    }
}
public class LoginDemo {
    public static void main(String[] args){
        Operate oper=new Operate(args);
        System.out.println(oper.login());
    }
}


🌳程序执行命令:


java LoginDemo 张三 123

🌳程序运行结果:


欢迎张三光临!


🌳程序的调用关系:

image.png


(2)单向链表实现(一)

所谓的链表就好像火车车厢一样,从火车头开始,每一节车厢之后都连着后一节车厢(通过引用传递的方式进行实现)


🌳代码如下:


class Node{
    private String data;//保存节点内容
    private Node next;//保存下一个节点
    public Node(String data){
        this.data=data;
    }
    public String getData(){
        return this.data;
    }
    public void setNext(Node next){
        this.next=next;
    }
    public Node getNext(){
        return this.next;
    }
}
public class LinkDemo1 {
    public static void main(String[] args){
        Node root=new Node("火车头");//定义根节点
        Node n1=new Node("车厢-A");//定义车厢
        Node n2=new Node("车厢-B");
        Node n3=new Node("车厢-C");
        root.setNext(n1);//火车头的下一个节点是第一节车厢
        n1.setNext(n2);
        n2.setNext(n3);
        printNode(root);
    }
    public static void printNode(Node node){
        System.out.print(node.getData()+"\t");
        if(node.getNext()!=null){
            printNode(node.getNext());
        }
    }
}


🌳运行结果:


火车头 车厢-A 车厢-B 车厢-C


printNode()方法就是采用了递归的调用形式,有时也可以把这种输出形式称为迭代输出。


(3)单向链表实现(二)

如果程序要按照(一)的方式操作肯定会很麻烦,因为要由用户手工去处理各个节点的关系,这样肯定是不行的,所以最好将节点的操作进行封装,这样用户使用起来就会比较方便。

假设现在的节点操作有增加数据、查找数据、删除数据3种。如果要删除节点,则直接修改上一个节点的引用即可


🌳代码如下:


class Link{
    class Node{    //节点类定义为内部类
        private String data;
        private Node next;
        public Node(String data){
            this.data=data;
        }
        public void add(Node newNode){
            if(this.next==null){    //判断下一个节点是否为空
                this.next=newNode;  //如果为空,把新节点设置在next位置上
            }else{
                this.next.add(newNode);
            }
        }
        public void print(){
            System.out.print(this.data+"\t");
            if(this.next!=null){    //如果下一个节点不为空,让下一个节点输出
                this.next.print();
            }
        }
        public boolean search(String data){   //定义一个搜索方法
            if(data.equals(this.data)){      //判断当前节点的名字是否与查找的一致
                return true;
            }else{        //判断下一个
                if(this.next!=null){  //下一个存在,继续查找
                    return this.next.search(data);   //返回下一个查询结果
                }else{
                    return false;
                }
            }
        }
        public void delete(Node previous,String data){  //删除节点
            if(data.equals(this.data)){   //找到匹配节点
                previous.next=this.next;   //空出当前节点
            }else{
                if(this.next!=null){
                    this.next.delete(this,data);
                }
            }
        }
    }
    private Node root;  //根节点
    public void addNode(String data){  //增加节点的方法
        Node newNode=new Node(data);   //建立新节点
        if(this.root==null){
            this.root=newNode;      //将第一个节点设置成根节点
        }else{
            this.root.add(newNode);  //添加到合适的位置
        }
    }
    public void printNode(){  //打印全部节点
        if(this.root!=null){   //判断是否存在根节点
            this.root.print();
        }
    }
    public boolean contains(String name){  //判断元素是否存在
        return this.root.search(name);     //调用Node中search()方法
    }
    public void deleteNode(String data){
        if(this.contains(data)){     //如果节点存在,则执行删除操作
            if(this.root.data.equals(data)){   //判断根节点是否满足要求
                this.root=this.root.next;    //将根节点之后的内容设置成根节点
            }else{
                this.root.next.delete(root,data);//删除节点
            }
        }
    }
}
public class LinkDemo2 {
    public static void main(String[] args){
        Link l=new Link();
        l.addNode("A");
        l.addNode("B");
        l.addNode("C");
        l.addNode("D");
        l.addNode("E");
        System.out.println("--------删除之前--------");
        l.printNode();
        l.deleteNode("C");
        l.deleteNode("D");
        System.out.println();
        System.out.println("--------删除之后--------");
        l.printNode();
        System.out.println();
        System.out.println("查询节点:"+l.contains("A"));
    }
}


🌳运行结果:

--------删除之前--------
A B C D E
--------删除之后--------
A B E
查询节点:true


以上程序对要操作的节点类进行了包装,以后用户直接调用包装后的类,即可方便地执行节点的增加、删除、查找操作。

目录
相关文章
|
21天前
|
搜索推荐 Java
Java的面向对象特性主要包括封装、继承和多态
【4月更文挑战第5天】Java的面向对象特性主要包括封装、继承和多态
15 3
|
1月前
|
Java 关系型数据库
JAVA面向对象设计原则
JAVA面向对象设计原则
12 1
|
1月前
|
算法 Java
java面向对象和面向过程分析
java面向对象和面向过程分析
38 0
|
1月前
|
Java
java面向对象高级分层实例_实体类
java面向对象高级分层实例_实体类
10 1
|
1月前
|
Java 物联网 测试技术
Java面向对象程序设计3面向对象基础
Java面向对象程序设计3面向对象基础
169 0
|
1天前
|
安全 Java
Java基础&面向对象&继承&抽象类
Java基础&面向对象&继承&抽象类
|
1天前
|
Java
【Java基础】详解面向对象特性(诸如继承、重载、重写等等)
【Java基础】详解面向对象特性(诸如继承、重载、重写等等)
5 0
|
7天前
|
安全 Java 机器人
《Java 简易速速上手小册》第2章:面向对象的 Java(2024 最新版)
《Java 简易速速上手小册》第2章:面向对象的 Java(2024 最新版)
19 0
|
10天前
|
存储 Java
Java基础教程(7)-Java中的面向对象和类
【4月更文挑战第7天】Java是面向对象编程(OOP)语言,强调将事务抽象成对象。面向对象与面向过程的区别在于,前者通过对象间的交互解决问题,后者按步骤顺序执行。类是对象的模板,对象是类的实例。创建类使用`class`关键字,对象通过`new`运算符动态分配内存。方法包括构造函数和一般方法,构造函数用于对象初始化,一般方法处理逻辑。方法可以有0个或多个参数,可变参数用`类型...`定义。`this`关键字用于访问当前对象的属性。
|
13天前
|
存储 Java 编译器
对象的交响曲:深入理解Java面向对象的绝妙之处
对象的交响曲:深入理解Java面向对象的绝妙之处
46 0
对象的交响曲:深入理解Java面向对象的绝妙之处