文章目录

  • 前言
  • 1.构造方法
    • (1)构造方法的概念和应用
    • (2)构造方法的作用
  • 2.方法重载
    • (1)重载的概念和体现形式
    • (2)方法重载的简单应用
    • (3)重载的实际意义
  • 3.this关键字
    • (1)this关键字的基本概念
    • (2)this关键字的工作原理
    • (3)this关键字的使用方式
      • Ⅰ 使用方式一
      • Ⅱ 使用方式二
      • Ⅲ 使用方式三
    • (4)引用类型变量的注意事项
  • 4.方法递归调用
    • (1)阶乘的计算
    • (2)递归方式的本质和注意事项
    • (3)斐波拉契数列的递归实现
  • 5.封装
    • (1)代码的拆分实现
    • (2)封装的概念
    • (3)封装的实现
    • (4)封装类实现学生信息的录入
    • (5)JavaBean的概念
  • 总结

前言

本文主要介绍了成员方法和面向对象的特性之一封装,主要包括构造方法、方法重载、this关键字、方法的递归调用和封装,包含了概念基础和应用举例,适合初学者。

1.构造方法

(1)构造方法的概念和应用

格式为:

class 类名 {类名(形参列表) {构造方法体;}
}

构造方法的特点为:

方法名与类名相同;

没有返回值类型,也不需要void类型。

如下:

/*构造方法的使用
*/public class MethodPerson {String name;int age;// 自定义构造方法MethodPerson() {System.out.println("执行了自定义的构造方法");}// 自定义成员方法void printVariable() {System.out.println("我是" + name + ",今年" + age + "岁了");}public static void main(String[] args) {// 1.声明一个Person类型的引用指向Person类型的对象MethodPerson p = new MethodPerson();// 2.打印特征p.printVariable();}
}

输出:

执行了自定义的构造方法
我是null,今年0岁了

可以看到,调用了定义的构造方法Person() ,但是我们之前的例子中都没有定义构造方法,也能正常运行,这是因为当类中没有定义构造方法时,编译器会自动添加无参空构造构造方法,即默认构造方法、缺省构造方法,如Person(){}

若类中提供了构造方法,则编译器不再提供构造方法。

(2)构造方法的作用

如果想要在构建对象的同时,自定义成员变量的初始值,就需要自定义构造方法;

如果需要在创建不同对象的同时,其成员变量的值不同,就可以传递参数。

如下:

/*构造方法的使用
*/public class MethodPerson {String name;int age;// 自定义构造方法MethodPerson(String s, int i) {System.out.println("执行了" + s + "的构造方法");name = s;age = i;}// 无参构造方法MethodPerson() {}// 自定义成员方法void printVariable() {System.out.println("我是" + name + ",今年" + age + "岁了");}public static void main(String[] args) {// 1.声明一个Person类型的引用指向Person类型的对象MethodPerson p1 = new MethodPerson("Corley", 18);// 2.打印特征p1.printVariable();MethodPerson p2 = new MethodPerson("Jack", 20);// 2.打印特征p2.printVariable();MethodPerson p3 = new MethodPerson();// 2.打印特征p3.printVariable();}
}

输出:

执行了Corley的构造方法
我是Corley,今年18岁了
执行了Jack的构造方法
我是Jack,今年20岁了
我是null,今年0岁了

可以看到,可以同时定义有参和无参的构造方法,便于在创建对象时传递或者不传递参数都可以成功创建对象。

可以总结:

使用new关键字创建对象时会自动 调用构造方法实现成员变量的初始化。

再在Point类中实现构造方法,如下:

/*Point类中实现构造方法
*/public class MethodPoint {int x;int y;// 自定义无参构造方法MethodPoint() {}// 自定义有参构造方法MethodPoint(int i, int j) {x = i;y = j;}void show() {System.out.println("横坐标是" + x + ",纵坐标是" + y);}public static void main(String[] args) {// 1.使用无参方式构造对象并打印成员变量MethodPoint p1 = new MethodPoint();p1.show();// 2.使用有参方式构造对象并打印成员变量MethodPoint p2 = new MethodPoint(12, 20);p2.show();}
}

输出:

横坐标是0,纵坐标是0
横坐标是12,纵坐标是20

2.方法重载

(1)重载的概念和体现形式

方法名称相同、参数列表不同,则这些方法之间构成重载(Overload) 关系。

示意如下:

/*方法重载
*/public class OverloadTest {// 自定义构造方法void show() {System.out.println("Showing...");}void show(int i) {System.out.println("Showing " + i);}void show(int i, double d) {System.out.println("Showing " + i + " " + d);}void show(int i, int j) {System.out.println("Showing " + i + " " + j);}void show(double d, int i) {System.out.println("Showing " + i + " " + d);}/*void show(double a, int b) {  // 报错,与参数变量名无关System.out.println("Showing " + a + " " + b);}*//*int show(double d, int i) {    // 报错,与返回值类型无关System.out.println("Showing " + i + " " + d);}*/public static void main(String[] args) {// 1.声明OverloadTest类型的引用指向该类型的对象OverloadTest ot = new OverloadTest();// 2.调用成员方法ot.show();ot.show(123);ot.show(123, 123.456);ot.show(123, 456);ot.show(123.456, 123);}
}

输出:

Showing...
Showing 123
Showing 123 123.456
Showing 123 456
Showing 123 123.456

方法重载的体现形式总结如下:

  • 方法参数的个数不同

  • 方法参数的类型不同

  • 方法参数的顺序不同

  • 与返回值类型和形参变量名无关

    建议返回值类型相同

判断方法能否构成重载的核心∶

调用方法时能否加以区分

(2)方法重载的简单应用

MethodPerson类中实现方法重载,如下:

/*构造方法的使用
*/public class MethodPerson {String name;int age;// 自定义构造方法MethodPerson(String s, int i) {System.out.println("执行了" + s + "的构造方法");name = s;age = i;}// 无参构造方法MethodPerson() {}// 自定义成员方法实现年龄增长1岁void grow() {age++;}// 自定义成员方法实现年龄增长指定数值void grow(int a) {age += a;}// 自定义成员方法void printVariable() {System.out.println("我是" + name + ",今年" + age + "岁了");}public static void main(String[] args) {// 1.声明一个Person类型的引用指向Person类型的对象MethodPerson p1 = new MethodPerson("Corley", 18);// 2.打印特征p1.printVariable();MethodPerson p2 = new MethodPerson("Jack", 20);p2.printVariable();MethodPerson p3 = new MethodPerson();p3.printVariable();System.out.println("----------------------------------------------");// 3.重载方法的调用和测试p2.grow();p2.printVariable();p2.grow(5);p2.printVariable();}
}

输出:

执行了Corley的构造方法
我是Corley,今年18岁了
执行了Jack的构造方法
我是Jack,今年20岁了
我是null,今年0岁了
----------------------------------------------
我是Jack,今年21岁了
我是Jack,今年26岁了

MethodPoint类中实现方法重载,如下:

/*Point类中实现构造方法
*/public class MethodPoint {int x;int y;// 自定义无参构造方法MethodPoint() {}// 自定义有参构造方法MethodPoint(int i, int j) {x = i;y = j;}void show() {System.out.println("横坐标是" + x + ",纵坐标是" + y);}// 实现纵坐标减1void down() {y--;}// 实现纵坐标减去指定数值void down(int dy) {y -= dy;}public static void main(String[] args) {// 1.使用无参方式构造对象并打印成员变量MethodPoint p1 = new MethodPoint();p1.show();// 2.使用有参方式构造对象并打印成员变量MethodPoint p2 = new MethodPoint(12, 20);p2.show();System.out.println("-----------------------------------");// 3.调用重载方法p2.down();p2.show();p2.down(5);p2.show();}
}

输出:

横坐标是0,纵坐标是0
横坐标是12,纵坐标是20
-----------------------------------
横坐标是12,纵坐标是19
横坐标是12,纵坐标是14

(3)重载的实际意义

方法重载的实际意义在于只需要记住一个方法名就可以调用各种不同的版本、实现不同的功能。

例如对于我们经常用的打印的方法java.io.FilterOutputStream.println() 就实现了方法的重载,所以可以打印各种类型的变量,如下:

方法 含义
println() 通过写行分隔符字符串来终止当前行。
println​(boolean x) 打印一个布尔值,然后终止该行。
println​(char x) 打印一个字符,然后终止该行。
println​(char[] x) 打印一个字符数组,然后终止该行。
println​(double x) 打印一个双,然后终止该行。
println​(float x) 打印一个浮点数,然后终止该行。
println​(int x) 打印一个整数,然后终止该行。
println​(long x) 打印一个长,然后终止该行。
println​(Object x) 打印一个对象,然后终止该行。
println​(String x) 打印一个字符串,然后终止该行。

方法重载的使用场景:

如果需要定义构造方法,需要使用方法重载;

如果需要定义功能类似、但是参数可能不同的方法,需要使用方法重载。

3.this关键字

(1)this关键字的基本概念

this关键字的含义:

  • 若在构造方法中出现了this关键字,则代表当前正在构造 的对象;

  • 若在成员方法中出现了this关键字,则代表当前正在调用 的对象。

  • this关键字本质上是当前类类型的引用变量

/*this关键字的使用
*/public class ThisTest {// 自定义构造方法ThisTest() {System.out.println("构造方法中,this = " + this);}void print() {System.out.println("成员方法中,this = " + this);}public static void main(String[] args) {// 1.声明ThisTest类型的引用指向该类型的对象ThisTest tt = new ThisTest();System.out.println("main方法中,tt = " + tt);// 2.调用print方法tt.print();}
}

输出:

构造方法中,this = ThisTest@50eac852
main方法中,tt = ThisTest@50eac852
成员方法中,this = ThisTest@50eac852

可以看到,在构造方法中的this所代表的对象和new 得到的对象是同一个对象。

(2)this关键字的工作原理

this关键字是当前类类型的引用,也是构造方法和成员方法中隐含的关键字。

之前在成员方法和构造方法中使用成员变量时,直接使用了成员变量名,与main方法中引用.成员变量名 的形式有所区别,例如System.out.println("我是" + name + ", 年龄是" + age + "岁了");,这是因为隐藏了关键字this,等价于System.out.println("我是" + ``this.name`` + ", 年龄是" + this.age + "岁了"); ,执行效果是相同的。

this关键字的工作原理如下:

在构造方法中和成员方法中访问成员变量时,编译器会加上this的前缀,而this.相当于汉语中"我的" ,当不同的对象调用同一个方法时,由于调用方法的对象不同导致this关键字所代表的对象随之不同,从而this.方式访问的结果也就随之不同。

(3)this关键字的使用方式

Ⅰ 使用方式一

之前在定义成员方法时,一般都是保证形参变量名与成员变量不同。但是为了增加代码的可读性,还是应该让形参变量名与成员变量保持一致。

由于就近原则,当局部变量名与成员变量名相同时,在方法体中会优先使用较近的局部变量(形参变量)、而不是成员变量,若希望使用成员变量,则可以在成员变量的前面加上this前缀,明确声明该变量是成员变量。

MethodPerson类使用this进行修改如下:

/*构造方法的使用
*/public class MethodPerson {String name;int age;// 自定义构造方法MethodPerson(String name, int age) {System.out.println("执行了" + name + "的构造方法");this.name = name;this.age = age;}// 无参构造方法MethodPerson() {}// 自定义成员方法实现年龄增长1岁void grow() {age++;}// 自定义成员方法实现年龄增长指定数值void grow(int age) {this.age += age;}// 自定义成员方法void printVariable() {// System.out.println("我是" + name + ",今年" + age + "岁了");System.out.println("我是" + this.name + ", 年龄是" + age + "岁了");}public static void main(String[] args) {// 1.声明一个Person类型的引用指向Person类型的对象MethodPerson p1 = new MethodPerson("Corley", 18);// 2.打印特征p1.printVariable();MethodPerson p2 = new MethodPerson("Jack", 20);p2.printVariable();MethodPerson p3 = new MethodPerson();p3.printVariable();System.out.println("----------------------------------------------");// 3.重载方法的调用和测试p2.grow();p2.printVariable();p2.grow(5);p2.printVariable();}
}

效果与之前相同。

MethodPoint类也可以进行修改,如下:

/*Point类中实现构造方法
*/public class MethodPoint {int x;int y;// 自定义无参构造方法MethodPoint() {}// 自定义有参构造方法MethodPoint(int x, int y) {this.x = x;this.y = y;}void show() {System.out.println("横坐标是" + x + ",纵坐标是" + y);}// 实现纵坐标减1void down() {y--;}// 实现纵坐标减去指定数值void down(int y) {this.y -= y;}public static void main(String[] args) {// 1.使用无参方式构造对象并打印成员变量MethodPoint p1 = new MethodPoint();p1.show();// 2.使用有参方式构造对象并打印成员变量MethodPoint p2 = new MethodPoint(12, 20);p2.show();System.out.println("-----------------------------------");// 3.调用重载方法p2.down();p2.show();p2.down(5);p2.show();}
}

Ⅱ 使用方式二

this关键字除了可以通过this. 的方式调用成员变量和成员方法,还可以作为方法的返回值

/*构造方法的使用
*/public class MethodPerson {String name;int age;// 自定义构造方法MethodPerson(String name, int age) {System.out.println("执行了" + name + "的构造方法");this.name = name;this.age = age;}// 无参构造方法MethodPerson() {}// 自定义成员方法实现年龄增长1岁void grow() {age++;}// 自定义成员方法实现年龄增长指定数值void grow(int age) {// 调用成员变量this.age += age;}// 自定义成员方法获取并返回Person类型对象MethodPerson getPerson() {// this作为方法的返回值return this;}// 自定义成员方法void printVariable() {// 调用成员方法this.grow();System.out.println("我是" + this.name + ", 年龄是" + age + "岁了");}public static void main(String[] args) {// 1.声明一个Person类型的引用指向Person类型的对象MethodPerson p1 = new MethodPerson("Corley", 18);// 2.打印特征p1.printVariable();MethodPerson p2 = new MethodPerson("Jack", 20);p2.printVariable();MethodPerson p3 = new MethodPerson();p3.printVariable();System.out.println("----------------------------------------------");// 3.重载方法的调用和测试p2.grow();p2.printVariable();p2.grow(5);p2.printVariable();System.out.println("----------------------------------------------");// 4.调用成员方法获取返回值MethodPerson p4 = p1.getPerson();System.out.println("p1 = " + p1);System.out.println("p4 = " + p4);}
}

输出:

执行了Corley的构造方法
我是Corley, 年龄是19岁了
执行了Jack的构造方法
我是Jack, 年龄是21岁了
我是null, 年龄是1岁了
----------------------------------------------
我是Jack, 年龄是23岁了
我是Jack, 年龄是29岁了
----------------------------------------------
p1 = MethodPerson@2a3b5b47
p4 = MethodPerson@2a3b5b47

Ⅲ 使用方式三

构造方法的第一行 可以使用this()的方式来调用本类中的其他构造方法

/*this的使用方式3
*/public class Boy {String name;Boy() {// 调用本类中的有参构造方法this("Jack");System.out.println("无参构造方法...");}Boy(String name) {System.out.println("有参构造方法...");this.name = name;}void print() {System.out.println("我的名字是" + name);}public static void main(String[] args) {// 1.无参方式构建对象Boy b1 = new Boy();b1.print();System.out.println("-----------------------------------");// 2.有参方式构造对象Boy b2 = new Boy("Corley");b2.print();}}

输出:

有参构造方法...
无参构造方法...
我的名字是Jack
-----------------------------------
有参构造方法...
我的名字是Corley

还可以如下:

/*this的使用方式3
*/public class Boy {String name;Boy() {// 调用本类中的有参构造方法// this("Jack");System.out.println("无参构造方法...");}Boy(String name) {this();System.out.println("有参构造方法...");this.name = name;}void print() {System.out.println("我的名字是" + name);}public static void main(String[] args) {// 1.无参方式构建对象Boy b1 = new Boy();b1.print();System.out.println("-----------------------------------");// 2.有参方式构造对象Boy b2 = new Boy("Corley");b2.print();}}

输出:

无参构造方法...
我的名字是null
-----------------------------------
无参构造方法...
有参构造方法...
我的名字是Corley

但是两个构造方法中不能都调用this() ,因为这样会出现互相调用,即递归调用 ,编译不能通过。

(4)引用类型变量的注意事项

引用类型变量用于存放对象的地址,可以给引用类型赋值为null,表示不指向任何对象。
当某个引用类型变量为null时无法对对象实施访问,因为它没有指向任何对象。此时,如果通过引用访问成员变量或调用方法,会产生NullPointerException异常。

例如:

/*this的使用方式3
*/public class Boy {String name;Boy() {// 调用本类中的有参构造方法// this("Jack");System.out.println("无参构造方法...");}Boy(String name) {this();System.out.println("有参构造方法...");this.name = name;}void print() {System.out.println("我的名字是" + name);}public static void main(String[] args) {// 1.无参方式构建对象Boy b1 = new Boy();b1.print();System.out.println("-----------------------------------");// 2.有参方式构造对象Boy b2 = new Boy("Corley");b2.print();// 3.自定义类型的引用变量为空Boy b3 = null;b3.print();}}

可以正常编译,但是解释执行时会抛出异常Exception in thread "main" java.lang.NullPointerException

声明引用类型的对象时,需要有明确的指向,即不能为空,因为如果为空说明该引用在栈区的内容为空,即没有指向的堆区空间,即该对象没有对应的数据空间,所以在调用方法或者访问成员变量时就会抛出异常。

4.方法递归调用

(1)阶乘的计算

编程实现参数n的阶乘并返回,所谓阶乘就是从1累乘到n的结果。

方式一:

通过for循环实现,即递推方式 。如下:

/*计算阶乘
*/public class FactorialTest {// 自定义方法计算参数n的阶乘并返回int fact(int n) {    int res = 1;for(int i = 1; i <= n; i++) {res *= i;}return res;}public static void main(String[] args) {// 1.声明FactorialTest类型的引用指向该类型的对象FactorialTest ft = new FactorialTest();// 2.调用方法进行计算int res = ft.fact(10);System.out.println("计算结果是:" + res);}
}

输出:

计算结果是:3628800

方式二:

根据阶乘的特点进行分析:

当n的值为1时,则阶乘的结果为1;

当n大于1时,n! = n * (n-1)!

即可以使用递归方式 ,代码如下:

/*计算阶乘
*/public class FactorialTest {// 自定义方法计算参数n的阶乘并返回int fact1(int n) {// 递推方式int res = 1;for(int i = 1; i <= n; i++) {res *= i;}return res;}int fact2(int n) {if (1 == n) return 1;return n * fact2(n-1);}public static void main(String[] args) {// 1.声明FactorialTest类型的引用指向该类型的对象FactorialTest ft = new FactorialTest();// 2.调用方法进行计算int res1 = ft.fact1(10);System.out.println("递推方式计算结果是:" + res1);int res2 = ft.fact2(10);System.out.println("递归方式计算结果是:" + res2);}
}

输出:

递推方式计算结果是:3628800
递归方式计算结果是:3628800

可以看到,执行结果完全相同,但是递归方式代码更简洁。

(2)递归方式的本质和注意事项

递归的本质是在方法体的内部直接或间接调用当前方法自身

使用递归的注意事项包括:

  • 使用递归必须要有递归的规律和终止条件

  • 使用递归必须使得问题简单化而不是复杂化;

  • 如果递归影响到程序的执行性能,则使用递推代之。

(3)斐波拉契数列的递归实现

编程实现斐波拉契数列中第n项的数值并返回。
斐波拉契数列: 1 1 2 3 5 8 13 21 ……

先用递归方式,进行分析:

如果n为1或者2,结果是1;

否则结果是前两项的和。

实现如下:

/*斐波拉契数列的实现
*/public class FibonacciSequence {// 1.递归实现斐波拉契数列int fib(int n) {if(1 == n || 2 == n) return 1;return fib(n-1) + fib(n-2);}public static void main(String[] args) {// 1.声明FibonacciSequence类型的引用指向该类型的引用FibonacciSequence fs = new FibonacciSequence();int res = fs.fib(10);// 2.打印计算结果System.out.println("计算结果是:" + res);}
}

输出:

计算结果是:55

分析递归的过程可以发现,这种方式实现斐波拉契数列的性能较低,如果n较大时就会运行很长时间,因为拆数和调用重复方法的次数较多,出现了大量计算(包括重复计算)。

现使用递推方式实现,如下:

/*斐波拉契数列的实现
*/public class FibonacciSequence {// 1.递归实现斐波拉契数列int fib1(int n) {if(1 == n || 2 == n) return 1;return fib1(n-1) + fib1(n-2);}// 2.递推实现斐波拉契数列int fib2(int n) {int x = 1;int y = 1;for(int i = 3; i <= n; i++) {int z = x + y;x = y;y = z;}return y;}public static void main(String[] args) {// 1.声明FibonacciSequence类型的引用指向该类型的引用FibonacciSequence fs = new FibonacciSequence();// 2.调用方式计算并打印计算结果int res1 = fs.fib1(10);System.out.println("递归计算结果是:" + res1);int res2 = fs.fib2(10);System.out.println("递推计算结果是:" + res2);}
}

输出:

递归计算结果是:55
递推计算结果是:55

5.封装

(1)代码的拆分实现

在开发中,不建议将成员方法和main方法放在同一个类中,因为main方法不是这个类独有的,这样会显得代码结构不够明确、清晰,应该在实现功能时创建功能类 ,在这个类中只放这个类的成员变量和成员方法,而将main方法放到测试类 (类名一般以Test结尾)中,即将代码实现物理上的拆分 、结构更清晰、可维护性更高,同时可以实现代码的复用

以上面的FibonacciSequence 类为例,进行拆分,功能类FibonacciSequence.java如下:

/*斐波拉契数列的实现 功能类
*/public class FibonacciSequence {// 1.递归实现斐波拉契数列int fib1(int n) {if(1 == n || 2 == n) return 1;return fib1(n-1) + fib1(n-2);}// 2.递推实现斐波拉契数列int fib2(int n) {int x = 1;int y = 1;for(int i = 3; i <= n; i++) {int z = x + y;x = y;y = z;}return y;}}

测试类FibonacciSequenceTest.java如下:

/*实现对斐波拉契类的测试 测试类
*/public class FibonacciSequenceTest {public static void main(String[] args) {// 1.声明FibonacciSequence类型的引用指向该类型的引用FibonacciSequence fs = new FibonacciSequence();// 2.调用方式计算并打印计算结果int res1 = fs.fib1(10);System.out.println("递归计算结果是:" + res1);int res2 = fs.fib2(10);System.out.println("递推计算结果是:" + res2);}
}

此时需要先编译、再执行,不能直接java filename 来运行。

先编译javac FibonacciSequenceTest.java,会同时生成FibonacciSequence.javaFibonacciSequenceTest.java的字节码文件,再执行java FibonacciSequenceTest

(2)封装的概念

封装是面向对象的一大特性。

通常情况下可以在测试类中给成员变量赋值一些合法但不合理的数值,无论是编译阶段还是运行阶段都不会报错或者给出提示,但是会与现实生活中的情况不符。

新建Student功能类:

/*Student类的封装
*/public class Student {int id; // 学号String name; // 姓名void print() {System.out.println("我是" + name + ",我的学号是" + id);}
}

再建测试类:

/*Student类的测试类
*/public class StudentTest {public static void main(String[] args) {// 1.声明Student类型的引用指向Student类型的对象Student stu1 = new Student();Student stu2 = new Student();// 2.对成员变量赋值并打印stu1.id = 12321;stu1.name = "Corley";stu1.print();stu2.id = -12321;stu2.name = "Jack";stu2.print();}
}

输出:

我是Corley,我的学号是12321
我是Jack,我的学号是-12321

可以看到,在给stu2进行赋值时,id为负值,这符合Java中整型的标准,即是合法的,但是与现实生活中的情况并不相符,因为没有学号是负值。

为了避免上述错误的发生,就需要对成员变量进行密封包装处理,来隐藏成员变量的细节 以及保证成员变量数值的合理性 ,该机制就叫做封装

(3)封装的实现

封装的实现步骤如下:

  1. 私有化成员变量,使用private 关键字修饰。

    private关键字修饰表示私有的含义,也就是该成员变量只能在当前类的内部使用

    之前访问成员变量的方式失效,例如stu2.id`` = -12321; 就不能再正常编译通过。

  1. 提供公有的get和set方法,并在方法体中进行合理值的判断。

    使用public关键字修饰,该方法可以在任意位置使用

    没有修饰符的方法和变量是默认的访问权限,级别介于private和public之间。

  1. 在构造方法中调用set方法进行合理值的判断。

Student类如下:

/*Student类的封装
*/public class Student {// 1.私有化成员变量,使用private关键字修饰private int id; // 学号private String name; // 姓名public Student() {}// 3.在公有的构造方法中调用set方法进行合理值的判断public Student(int id, String name) {setId(id);setName(name);}// 2.提供公有的get和set方法,并在方法体中进行合理值的判断public int getId() {return id;}public void setId(int id) {if (id > 0) {this.id = id;} else {System.out.println("学号不合理!!!");}}public String getName() {return name;}public void setName(String name) {this.name = name;}public void print() {System.out.println("我是" + getName() + ",我的学号是" + getId());}
}

StudentTest类如下:

/*Student类的测试类
*/public class StudentTest {public static void main(String[] args) {// 1.声明Student类型的引用指向Student类型的对象Student stu1 = new Student();Student stu2 = new Student();// 2.对成员变量赋值并打印/*stu1.id = 12321;stu1.name = "Corley";stu1.print();stu2.id = -12321;stu2.name = "Jack";stu2.print();*/stu1.setId(12321);stu1.setName("Corley");stu1.print();System.out.println("-------------------------------------------");stu2.setId(-12321);stu2.setName("Jack");stu2.print();System.out.println("-------------------------------------------");Student stu3 = new Student(-45654, "Bob");stu3.print();}
}

输出:

我是Corley,我的学号是12321
-------------------------------------------
学号不合理!!!
我是Jack,我的学号是0
-------------------------------------------
学号不合理!!!
我是Bob,我的学号是0

此时Student类就是封装类。

(4)封装类实现学生信息的录入

提示用户输入班级的学生人数以及每个学生的信息,学生的信息有:学号、姓名,最后分别打印出来。
提示:Student[] arr = new Student[num];

Student类使用前面定义的Student类,StudentTest类如下:

/*Student信息的录入和打印
*/import java.util.Scanner;public class StudentTest {public static void main(String[] args) {// 1.提示用户输入学生人数System.out.println("请输入学生人数:");Scanner sc = new Scanner(System.in);int count = sc.nextInt();// 2.根据人数声明对应的一维数组Student[] stus = new Student[count];// 3.提示用户输入每个学生的信息并保存到一维数组for (int i = 0; i < count; i++) {System.out.println("请输入第" + (i + 1) + "个学生的信息(学号 姓名):");stus[i] = new Student(sc.nextInt(), sc.next());}// 4.打印所有学生的信息System.out.println("所有学生的信息为:");for(int i = 0; i < count; i++) {stus[i].print();}}
}

输出:

请输入学生人数:
3
请输入第1个学生的信息(学号 姓名):
12321 Corley
请输入第2个学生的信息(学号 姓名):
12322 Jack
请输入第3个学生的信息(学号 姓名):
12323 Bob
所有学生的信息为:
我是Corley,我的学号是12321
我是Jack,我的学号是12322
我是Bob,我的学号是12323

其中,Student[] stus = new Student[count]; 的含义是:

数组中的每个元素都是Student类型,即数组中的每个元素都可以看做Student类型的变量,所以对每个元素进行初始化时可以采用arr[i] = new Student(); 的方式。

(5)JavaBean的概念

JavaBean是一种Java语言写成的可重用组件,其他Java 类可以通过反射机制发现和操作这些JavaBean 的属性。
JavaBean本质上就是符合以下标准的Java类:

  • 类是公共的

  • 有一个无参的公共的构造器

  • 有属性,且有对应的get、set方法

可以看到,JavaBean其实就是一个封装类

总结

方法是一个类实现一定功能的基础,同时方法具有重载、递归等特性;作为面向对象的三大特征之一,封装将对象内部的成员封闭起来,不对外开放,同时增加了对用户合理性的判断,防止了用户的恶意操作,从而保证了对象的完整性。

大数据开发基础入门与项目实战(一)Java SE之4.方法和封装相关推荐

  1. 大数据开发基础入门与项目实战(三)Hadoop核心及生态圈技术栈之5.即席查询Impala介绍及入门使用

    文章目录 前言 1.Impala概述 (1)Impala的概念和优势 (2)Impala的缺点及适用场景 2.Impala的安装与入门 (1)准备工作 (2)制作本地yum源 (3)安装Impala ...

  2. 大数据开发基础入门与项目实战(一)Java SE之1.初识计算机和Java语言

    文章目录 前言 1.计算机的体系结构 (1)计算机的基本概念 (2)常见的主要硬件 (3)主要硬件的详解 Ⅰ CPU Ⅱ 内存 Ⅲ 硬盘 Ⅳ 输入输出设备 (4)常见的主要软件 (5)计算机的体系结构 ...

  3. 大数据开发基础入门与项目实战(三)Hadoop核心及生态圈技术栈之3.数据仓库工具Hive基础

    文章目录 1.Hive概述 (1)数仓工具Hive的产生背景 (2)数仓工具Hive与RDBMS对比 (3)数仓工具Hive的优缺点 (4)数仓工具Hive的架构原理 2.Hive安装与配置 (1)安 ...

  4. 大数据开发基础入门与项目实战(三)Hadoop核心及生态圈技术栈之2.HDFS分布式文件系统

    文章目录 前言 1.HDFS特点 2.命令行和API操作HDFS (1)Shell命令行客户端 (2)API客户端连接HDFS的两种方式 (3)API客户端上传下载文件 (4)API客户端文件详情及文 ...

  5. 大数据开发基础入门与项目实战(二)Java Web数据可视化之3.Linux概述、安装和结构

    文章目录 前言 1.Linux概述 (1)Linux简介 (2)Linux的应用领域及版本介绍 2.安装Linux (1)VMWare的安装 (2)使用VMWare构建虚拟机器 (3)安装CentOS ...

  6. 视频教程-20年Nodejs教程零基础入门到项目实战前端视频教程-Node.js

    20年Nodejs教程零基础入门到项目实战前端视频教程 7年的开发架构经验,曾就职于国内一线互联网公司,开发工程师,现在是某创业公司技术负责人, 擅长语言有node/java/python,专注于服务 ...

  7. 视频教程-全新大数据企业电商数据仓库项目实战教程-大数据

    全新大数据企业电商数据仓库项目实战教程 张长志技术全才.擅长领域:区块链.大数据.Java等.10余年软件研发及企业培训经验,曾为多家大型企业提供企业内训如中石化,中国联通,中国移动等知名企业.拥有丰 ...

  8. 2018年最新Vue从基础入门到项目实战视频教程网盘学习地址

    2018年最新Vue从基础入门到项目实战视频教程网盘学习地址: https://pan.baidu.com/s/15D6GiHnSgA5Eo0n9G5Ws1A 若网盘地址失效,可访问此地址(下单有网盘 ...

  9. react从零基础入门到项目实战视频教程

    React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站, 并于 2013年 5 月开源.React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它.这 ...

  10. 大数据入门培训之大数据开发基础知识学习

    在目前相信大多数IT开发人员对于人工智能+大数据并不陌生,使用的场景也越来越广,日常开发中前端同学也逐渐接触了更多与大数据相关的开发需求.因此对大数据知识也有必要进行一些学习理解,带大家来学习了解一下 ...

最新文章

  1. 安卓心理测试实训代码_我是如何从测试转到开发的
  2. shell中数字大小的比较
  3. linux6.6挂载u盘失败,mini2440 Linux系统自动挂载U盘与SD卡失败 解决方法
  4. python基本输入与格式化_Python导学基础(三)输入、格式化输出、基本运算符
  5. 【AI面试题】回归问题常用的性能度量指标(评价指标)
  6. android 判断字符相等,字符串的截取,判断字符串是否相等和字符串是否为空的方法总结Java,Android...
  7. Linux下基本TCP socket编程之客户端
  8. nginx内核优化及配置
  9. 一个app管理平台-app-host的搭建
  10. 阿里云Flink SQL开发指南——字符串函数——REGEXP_REPLACE正则替换
  11. web前端网页设计期末课程大作业:旅游网页主题网站设计——紫色的旅游开发景点网站静态模板(4页)HTML+CSS+JavaScript
  12. 磁盘阵列恢复方法以及注意事项
  13. xshell如何使用
  14. CodeForces 366C Dima and Salad
  15. 为自己的博客系统写的一篇自我介绍
  16. 实验室安全与危化品信息管理平台建设
  17. 趋势 | 极简再见,极繁回潮
  18. 叉积 微分 恒等式_不等式(O):常见符号及恒等式
  19. Mac OS下MAT(Memory Analyzer Tool)安装与启动
  20. 什么样的男人能轻松泡到妞?

热门文章

  1. Visio画正态分布曲线
  2. word文档怎么找回误删的文件_Word文档删除了怎么恢复?Word误删除恢复技巧
  3. PHP控制连接打印机
  4. bgp (二)改变下一跳本地,
  5. 【web前端性能优化】12.css sprite(图片精灵)-雪碧图实现原理
  6. 大学计算机考试考操作吗,大学计算机期末考试系统操作流程.doc
  7. 阿里云服务器可以搭建游戏吗?
  8. 学计算机的一直对画画感兴趣,[电脑绘画兴趣小组教学总结]sai电脑绘画入门教学...
  9. vs配置python环境_VS2017中安装Python开发环境[TZZ]
  10. WinDynamicDesktop下载慢解决方法