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


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

目录
相关文章
|
1月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
25 1
|
2月前
|
JavaScript 前端开发 Java
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。如果你从我的文章中受益,欢迎关注我,我将持续更新更多优质内容。你的支持是我前进的动力!🎉🎉🎉
26 0
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
|
2月前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
45 2
|
4月前
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
4月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
39 4
|
4月前
|
Java
接口和抽象类【Java面向对象知识回顾②】
本文讨论了Java中抽象类和接口的概念与区别。抽象类是不能被实例化的类,可以包含抽象和非抽象方法,常用作其他类的基类。接口是一种纯抽象类型,只包含抽象方法和常量,不能被实例化,且实现接口的类必须实现接口中定义的所有方法。文章还比较了抽象类和接口在实现方式、方法类型、成员变量、构造方法和访问修饰符等方面的不同,并探讨了它们的使用场景。
接口和抽象类【Java面向对象知识回顾②】
|
3月前
|
存储 Java 程序员
Java基础-面向对象
Java基础-面向对象
31 0
|
5月前
|
Java 数据处理 开发者
【Java基础面试十二】、说一说你对面向对象的理解
这篇文章阐述了面向对象是一种以类和对象为基础,通过封装、继承和多态等概念来模拟现实世界中的事物及其相互关系的程序设计方法,它强调以事物为中心进行思考和系统构造,与结构化程序设计相比,更符合人类的自然思维方式。
【Java基础面试十二】、说一说你对面向对象的理解
|
5月前
|
Java
【Java基础面试十三】、面向对象的三大特征是什么?
这篇文章介绍了面向对象程序设计的三大基本特征:封装、继承和多态,其中封装隐藏对象实现细节,继承实现软件复用,多态允许子类对象表现出不同的行为特征。
【Java基础面试十三】、面向对象的三大特征是什么?
|
4月前
|
安全 Java Go
面向对象程序设计语言:Java
Java语言语法和C语言和C++语言很接近,很容易学习和使用,Java丢弃了C++中很少使用的、很难理解的、令人迷惑的特性,Java语言不使用指针,而是引用,并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧
82 2