活动地址:CSDN21天学习挑战赛
🔭学习内容
- 掌握对象数组的概念及用法。
- 掌握内部类的特点及应用,以及内部类调用方法中参数的要求。
- 对学习内容进行实例分析。
✈️目录
🔭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
🌳程序运行结果:
欢迎张三光临!
🌳程序的调用关系:
(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
以上程序对要操作的节点类进行了包装,以后用户直接调用包装后的类,即可方便地执行节点的增加、删除、查找操作。