- java类及类的成员:**属性、方法、构造器;**代码块、内部类**面向对象的三大特征:**封装、继承、多态其他关键字:this、super、static、final、abstract、interface、package、import
面向过程(POP)与面向对象(OOP)
面向过程:强调的是功能、以函数为最小单位,考虑怎么做
面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做
面向对象的思维概述:
程序员从面相过程的执行着转化成了面向对象的指挥者面向对象分析方法分析问题的思路和步骤:
- 根据问题需要,选择问题所针对的现实世界中的实体。从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即接著某种程序语言,把类构造成计算机能够识别和处理的数据结构。将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。
类和(Class)和对象(Object)是面向对象的和性概念
类是对一类事物的描述,是抽象的、概念上的定义
对象是实际存在的该类事物的每个个体,因而也称为实例(instance)
万事万物皆对象
类
比如人、猪、狗、玩具、水果,对某一类实物的抽象
面向对象程序设计的重点是对类的设计
类的设计,就是设计类的成员
现实世界中的生物体,达到鲸鱼,小到蚂蚁,都是有最基本的细胞构成的。同理,Java代码世界是由诸多个不同功能的类构成的。类中的两个主要的成员:属性和方法
属性=成员变量=field=域、字段
方法=成员方法=函数=method
类和对象的创建与使用- 创建类,设计类的成员创建类的对象通过“对象.属性”或“对象.方法”调用对象的结构
public class Mini {
public static void main(String[] args) {
//实例化对象
Person p1 = new Person();
p1.name = "小狗蛋";
p1.sex = '女';
p1.age = 24;
p1.height = 158;
p1.eat();
p1.sleep();
p1.talk("中文");
}
}
class Person {
//属性:名字、性别、身高
String name;
int age;
char sex;
double height;
//方法:睡觉、吃法、说话
public void eat(){
System.out.println("人会吃饭");
}
public void sleep(){
System.out.println("人要睡觉");
}
public void talk(String language){
System.out.println("中国人说的是"+language);
}
}
如果创建了一个类的多个对象,则每个对象都独立拥有一套属性。(非static的)
也就是说,我们修改了一个对象的属性,并不会影响另一个对象的属性
对象的内存解析[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TOGaTTUu-1644334828455)(C:UserslinAppDataRoamingTyporatypora-user-imagesimage-20220111212301417.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O5LeUIsv-1644334828456)(C:UserslinAppDataRoamingTyporatypora-user-imagesimage-20220111213339194.png)]
属性(成员变量)与局部变量的对比相同点
- 定义变量的格式相同:数据类型 变量名 = 变量值;先声明,后使用变量都有其对应的作用域
不同点
- 定义的位置不同:
成员变量:直接定义在类中的变量,在类的大括号{}里面局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量 关于权限修饰符的不同:
属性可以在声明属性时,使用权限修饰符指明其权限。常用的权限修饰符:public、private、protected 、缺省(未声明权限修饰符)–>封装性局部变量不能使用权限修饰符,他的权限与方法的权限一致。 默认初始化值的情况:
属性:类的属性,根据其基本类型,都有默认初始化值。
整形(byte、short、int、long):0浮点型(float、double):0.0字符型(char):0或u0000引用数据类型(类、数组、接口):null 局部变量:没有默认初始化值
意味着我们在调用局部变量时必须先赋值public (public static void main(String[] args) { //这里面的args(形式参数)也是局部变量)形式参数我们在调用时再赋值即可 在内存中加载的位置不同
- 属性:加载到堆空间中(非static)局部变量:加载到栈中
方法:描述该类具有的功能比如:
Math类:sqrt()random()…Scanner类:nextXxx()…Arrays类:sort()binarySearch()toString()equals()…
public class Text {
public static void main(String[] args) {
}
class Customer{
//属性
String name;
int age;
boolean married;
//方法的声明:权限修饰符 返回值 方法名(形式参数列表){方法体}
public void eat(String food){
System.out.println("客户去吃饭了,吃的是"+food);
}
public void sleep(){
System.out.println("客户现在在休息");
}
public String getName(){
return name;
}
public String getNation(String nation){
String info ="我的国籍是:"+ nation;
return info;
}
}
}
方法声明的说明
- 关于权限修饰符(四个):private、public、缺省、protected–>封装性再细讲返回值类型:有返回值 & 没有返回值
**如果方法有返回值:**必须在方法声明时指定返回值的类型。同时在方法中需要使用return 指定返回值类型的数据。**没有返回值:**在声明方法时,则需要使用void来表示。农场没有返回值的方法中,不需要使用return。也可以使用“return;”来结束方法,只有结束方法的作用,后面的语句不能执行。 方法名:属于标识符,需要满足首字母大写,驼峰原则,需要见名知意。形参列表:方法可以声明0个、一个或者多个形参
- 格式:数据类型1 形参1,数据类型2 形参2,…我们定义方法时,是否需要定义形参:视情况而定
- 使用范围:使用在方法体中作用:
- 结束方法针对有返回值类型的方法, 使用“return 数据”方法返回所要的数据
- 方法在使用中可以调用当前类的属性及当前类中的方法
可以调用别的方法也可以调用自己(递归)
package OOP.Circle;
//利用面向对象的方法,设计Circle类计算园的面积
public class CircleText {
public static void main(String[] args) {
Circle cir = new Circle();
cir.radius = 3;
// double area = cir.getArea();
// System.out.println(area);
cir.getArea();
}
}
//方法一
//class Circle{
// double radius;
// public double getArea(){
// double area = Math.PI*radius*radius;
// return area;
// }
//
//}
//方法二
class Circle{
double radius;
public void getArea(){
System.out.println("圆的面积为:"+Math.PI*radius*radius);
}
}
打印自定义矩形
package OOP.Exer;
import java.util.Scanner;
public class RectangleText {
public static void main(String[] args) {
Rectangle rect = new Rectangle();
System.out.println("请输入长度m的值:");
rect.m = rect.getVal();
System.out.println("请输入宽度n的值:");
rect.n = rect.getVal();
rect.diagramPrint();
rect.printArea();
}
}
class Rectangle{
int m;
int n;
//输出面积
public void printArea(){
System.out.println("矩形面积为:"+m*n);
}
//打印图形
public void diagramPrint(){
System.out.println("打印矩形:");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print("*t");
}
System.out.println();
}
}
//创建一个从键盘接收数据的方法
public int getVal(){
int val = 0;
for (; ; ) {
Scanner sca = new Scanner(System.in);
if (sca.hasNextInt()){
val= sca.nextInt();
return val;
}else {
System.out.println("请输入正确的数据类型!");
}
}
}
}
打印学生信息
package OOP.Student;
public class StudentText {
public static void main(String[] args) {
Student[] student = new Student[20];//创建一个Student类型的数组
for (int i = 0; i < student.length; i++) {
student[i] = new Student();//给数组元素赋值,这个值就是Student类型的值。
student[i].number = i+1;
student[i].state = (int) (Math.random()*(6-1+1)+1);
student[i].score = (int) (Math.random()*(100-0+1)+0);
//输出三年级学生的信息
if (student[i].state == 3){
student[i].info();
}
}
//使用冒泡排序以成绩高低对学生进行排序
for (int i = 0; i < student.length-1; i++) {
for (int j = 0; j < student.length-1-i ; j++) {
if (student[j].score>student[j+1].score){
Student temp = student[j];
student[j] = student[j+1];
student[j+1] = temp;
}
}
}
//打印所有学生的信息
for (int i = 0; i < student.length-1; i++) {
student[i].info();
}
}
}
//创建类
class Student{
int number;//学号
int state;//年级
int score;//成绩
//打印学生信息的方法
public void info(){
System.out.println("学号"+number+"t年级:"+state+"t成绩:"+score);
}
}
改进
package OOP.Student;
public class StudentText {
public static void main(String[] args) {
Student[] student = new Student[20];//创建一个Student类型的数组
for (int i = 0; i < student.length; i++) {
student[i] = new Student();//给数组元素赋值,这个值就是Student类型的值。
student[i].number = i+1;
student[i].state = (int) (Math.random()*(6-1+1)+1);
student[i].score = (int) (Math.random()*(100-0+1)+0);
}
StudentText studentText = new StudentText();
System.out.println("打印指定年级的学生信息:");
studentText.searchInfo(student,3);
studentText.sort(student);//以成绩对学生信息进行排序
System.out.println("打印排序后的学生信息");
studentText.arrPrint(student);
}
public void searchInfo(Student[] stu,int state){
for (int i = 0; i < stu.length; i++) {
if (stu[i].state == state){
stu[i].info();
}
}
}
public void sort(Student[] stu){
for (int i = 0; i < stu.length-1; i++) {
for (int j = 0; j < stu.length-1-i ; j++) {
if (stu[j].score>stu[j+1].score){
Student temp = stu[j];
stu[j] = stu[j+1];
stu[j+1] = temp;
}
}
}
}
public void arrPrint(Student[] stu){
for (int i = 0; i < stu.length-1; i++) {
stu[i].info();
}
}
}
//创建类
class Student{
int number;//学号
int state;//年级
int score;//成绩
//打印学生信息的方法
public void info(){
System.out.println("学号"+number+"t年级:"+state+"t成绩:"+score);
}
}
面向对象 一 复习
1.面向对象学习的三条主线
- 类与类的成员:属性、方法、构造器;代码块、内部类面向对象的三大特性:封装、继承、多态其它关键字:static、interface、import、package、final、this…
- 面向过程:强调的是工程行为,以函数为最小单位,考虑怎么做面向对象:清点具备功能的对象,以类/对象为最小单位,考虑谁来做举例:人把大象放冰箱
- 根据问题的需要,选择问题所针对的现实世界中的实体。从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。
类:对一类事物的描述,是抽象的、概念上的定义对象:是实际存在的该类事物的每个个体,因而也被称为实例(instance)面向对象程序设计的重点是类的设计设计类,就是设计类的成员类是对象的抽象描述,对象是类的实例化 5.面向对象思想落地的规则一
- 创建类,设计类的成员实例化类,创建类的对象调用类中的属性和方法(“对象.方法”“对象的.属性”)
相同点:
命名规则规范相同都是先声明、后使用变量都具有其对应的作用域 异同:
声明的位置不同:属性是在类中声明的声明的。局部变量是在方法内、内部类、构造器内声明的,形式参数也属于局部变量。初始化值:属性(成员变量)有初始化值,局部变量没有初始化值(形式参数必须初始化值才能使用) 7.return关键字
适用范围作用 理解万物皆对象 理解“万事万物皆对象”
- 在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
Scanner,String文件:File网络资源:URL 涉及到Java语言与前端的Html、后端的数据库交互时,前后端的结构在Java层面交互时,头体现为类、对象。
- 引用类型的变量,只可能存储两类值:null或者地址值(含变量类型)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zgXsDTX7-1644334828457)(C:UserslinAppDataRoamingTyporatypora-user-imagesimage-20220113233156025.png)]
理解:匿名对象,我们创建对象时间
匿名对象不能重复使用,因为没有在栈空间中创建地址值,每一次调用都是一个新的对象
使用如下:
package OOP.Instance;
public class InstanceText {
public static void main(String[] args) {
Phone p = new Phone();
p.playGame();
p.sendEmail();
new Phone().price = 1999;//给匿名对象赋值
new Phone().showPrice();//此时打印出来的值为0,说明匿名对象只能使用一次
//匿名对象的使用
ShowMall mall = new ShowMall();
mall.show(new Phone());//此时打印出来的price为1996
}
}
class ShowMall{
public void show(Phone phone){
phone.price = 1996;
phone.sendEmail();
phone.readNews();
phone.readMovies();
phone.showPrice();
}
}
class Phone{
int price;
public void showPrice(){
System.out.println("此手机价格为:"+price);
}
public void sendEmail(){
System.out.println("发送邮件");
}
public void playGame(){
System.out.println("打游戏");
}
public void readNews(){
System.out.println("看新闻");
}
public void readMovies(){
System.out.println("看电影");
}
}
package OOP.ArrayUtil;
class ArrayUtil {
//求数组最大值
public int getMax(int[] arr){
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (maxarr[i]){
min = arr[i];
}
}
return min;
}
//求数组和
public int getSum(int[] arr){
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}
//求数组平均值
public int getAverage(int[] arr){
return getSum(arr)/arr.length;
}
//反转数组
public void reversal(int[] arr){
for (int i = 0; i < arr.length/2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length-i-1];
arr[arr.length-i-1] = temp;
}
}
//数组排序
public void sort(int[] arr){
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j+1]){
int y = arr[j];
arr[j] = arr[j+1];
arr[j+1] = y;
}
}
}
}
//复制数组
public int[] arrCopy(int[] arr){
int[] name = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
name[i] = arr[i];
}
return name;
}
//遍历数组
public void printArr(int[] arr){
for (int i = 0; i < arr.length-1; i++) {
System.out.print(arr[i]+"t");
}
System.out.println();
}
//查找指定元素,查找地址值
public int search(int[] arr,int val){
for (int i = 0; i < arr.length; i++) {
if (arr[i] == val){
return i;
}
}
return -1;
}
}
测试封装的工具类
package OOP.ArrayUtil;
public class ArrayUtilText {
public static void main(String[] args) {
int[] arr1 = new int[]{3,0,-1,2,99,88,12,-21};
ArrayUtil util = new ArrayUtil();
util.sort(arr1);
util.printArr(arr1);//打印数组
System.out.println("最大值:"+util.getMax(arr1));
System.out.println("最小值:"+util.getMin(arr1));
System.out.println("数组求和:"+util.getSum(arr1));
util.reversal(arr1);//反转数组
util.printArr(arr1);
System.out.println("在数组中找到元素,在数组中的位置为:"+(util.search(arr1,3)+1));
}
}
再谈方法
方法的重载
**重载的概念:**在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可。(两统一不同:同一个类,同一个方法名称,参数列表不同)
**重载的特点:**与返回值类型无关,只看参数列表,且参数列表必须不同(参数个数或者参数类型)。调用时,根据方法参数列表的不同来区别。
重载示例
返回两个整数的和:int add(int x, int y){return x+y;}
返回三个整数的和:int add(int x, int y,int z){return x+y+z;}
返回两个小数的和:double add(double x, double y){return x+y;}
package OOP.OverLoadText;
class OverLoadUtil {
//如下的四个方法就构成了重载
public void sum (int a,int b){
System.out.println(a+b);
}
public void sum (int a,double b){
System.out.println(a+b);
}
public void sum (double b,int a){
System.out.println(a+b);
}
public double sum (double b,int a,int c){
System.out.println(a+b);
return a + b + c;
}
}
在调用重载的方法时,如果确定调用的是哪一个方法:
先通过方法名–>再查看参数列表 可变形参数
- 可变形参数是jdk5.0的新特性具体使用:
- 可变个数形参格式:数据类型…变量名当调用可变个数形参的方法是,传入的参数个数可以是0个、一个或者多个可变个数形参的方法与本类中方法名相同,形参不同的方法直接构成重载可变个数形参的方法与本类中方法名相同,形参类型相同的数组之间不构成重载(不能共存)。其实与数组的参数是一样的可变形参数必须声明在参数列表的末尾,也就是只能声明一个可变型参数
方法必须由其所在类或对象调用才有意义。若方法含有参数
形参:方法声明时的参数
实参:方法调用时实际传给形参的参数值
Java的实参值如何传递给方法呢?
Java里方法的参数传地方是只有一种:值传递。即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响
形参是基本数据类型时:将实参基本数据类型变量的“数据值”传递给形参形参时引用数据类型时:将实参引用数据类型变量的“地址值”传递给形参,改变形参的值时,实参的值也会被改变
package OOP.ValueTransferText;
public class ValueTransferText {
public static void main(String[] args) {
Order or1 = new Order();
or1.orderId = 1001;
Order or2 =or1;//赋值以后,or1和or2指向堆空间中同一个对象实体
System.out.println("or1.orderId:"+or1.orderId+
",or2.orderId:"+or2.orderId);//两个输出的都是1001
or2.orderId= 1002;
System.out.println("or1.orderId:"+or1.orderId+
",or2.orderId:"+or2.orderId);
}
}
class Order{
int orderId;
}
错误示例
写方法时不能使用值传递,因为不会改变原参数的
解决方法:可以使用引用传递来进行参数调整
package OOP.ValueTransferText2;
public class ValueTransferText2 {
public static void main(String[] args) {
int x = 10;
int y = 20;
System.out.println(x+"--"+y);//输出10--20
ValueTransferText2 val = new ValueTransferText2();
val.swap(x,y);
System.out.println(x+"--"+y);
}
public void swap(int i,int j){
int temp = i;
i=j;
j=temp;
}
}
引用数据类型传递
引用传递使用:交换数据值
- 使用引用传递调换值
package OOP.ValueTransferText2;
public class ValueTransferText2 {
public static void main(String[] args) {
Date date = new Date();
date.x=10;
date.y=20;
System.out.println("date.x:t"+date.x+"tdate.y:t"+date.x);
ValueTransferText2 v2 = new ValueTransferText2();
v2.swap(date);
System.out.println("date.x:t"+date.x+"tdate.y:t"+date.y);
}
public void swap(Date date){
int temp = date.x;
date.x = date.y;
date.y=temp;
}
}
class Date{
int x,y;
}
- 创建调换位置的方法,在冒泡排序中进行调用
package OOP.ValueTransferText2;
import java.util.Arrays;
public class ValueTransferText2 {
public static void main(String[] args) {
//要调用本类中的方法
ValueTransferText2 v2 = new ValueTransferText2();
int[] x = new int[]{1,-2,30,9,7,25,15};
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < x.length-1-i; j++) {
if (x[j]>x[j+1]){
v2.swap(x,j,j+1);
}
}
}
System.out.println(Arrays.toString(x));
}
//创建方法时,调换数组中的参数,应为数组是引用数据类型,可以达到调换位置的目的
public void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j]=temp;
}
}
练习
1.创建一个类,让他包含一个double类型的半径(Radius),一个findAreas()方法返回一个double类型圆的面积
2.创建一个PassObject类,在类中定义一个方法printAreas(), 该方法的定义如下:public void printAreas(Circle circle,int time)。在printAreas中打印出1到time之间每个整数半径值,以及其对应的面积,
package OOP.ValueTransferText2;
public class ValueTransferText2 {
public static void main(String[] args) {
System.out.println("RadiustArea");
Circle circle = new Circle();
PassObject pso = new PassObject();
pso.printAreas(circle,6);
}
}
class Circle{
double radius;
public double findAreas(){
return Math.PI*radius*radius;
}
}
class PassObject{
public void printAreas(Circle c,int time){
int i = 1;
for (; i < time ; i++) {
c.radius = i;
System.out.println(c.radius+"tt"+c.findAreas());
}
System.out.println("n"+"now radius is:"+ (double)i);
}
}
递归
递归方法:一个方法体调用它自身。方法递归包含了一种隐式的循环,他会重复执行某段代码,但这种重复执行无需循环控制。递归一定要向已知方向递归,否则这种地柜就变成了无穷递归,类似于死循环。例1:求1~n的自然数之和
package OOP.ValueTransferText2;
public class ValueTransferText2 {
public static void main(String[] args) {
System.out.println(getSum(100));
}
//创建一个求从1到n的自然数之和方法
public static int getSum(int n){
if (n==1){
return 1;
}else {
return n+getSum(n-1);
}
}
}
例2求1~n的自然数阶乘
package OOP.ValueTransferText2;
public class ValueTransferText2 {
public static void main(String[] args) {
System.out.println(getSum(100));
}
//创建一个求1~n的自然数阶乘的方法
public static int getSum(int n){
if (n==1){
return 1;
}else {
return n*getSum(n-1);
}
}
}
例3,一直有一个数列:f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n),其中n是大于0的整数,求f(10)的值
package OOP.ValueTransferText2;
public class ValueTransferText2 {
public static void main(String[] args) {
System.out.println(getSum(10));
}
//创建一个求从1到n的自然数之和
public static int getSum(int n){
if (n==0){
return 1;
}else if(n==1) {
return 4;
}else {
return 2*getSum(n-1)+getSum(n-2);
}
}
}
例4,输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值,1 1 2 3 5 8 13 21 34 55
package OOP.ValueTransferText2;
public class ValueTransferText2 {
public static void main(String[] args) {
System.out.println(fbArr(10));
}
//斐波那契数列的第n个值的方法
public static int fbArr(int n){
if (n==1||n==2){
return 1;
}else {
return fbArr(n-1)+fbArr(n-2);
}
}
}
例5,汉诺塔问题例6,快速排序 复习
1.匿名对象的使用
2.理解万事万物皆对象
3.方法的重载
方法的重载与重写的区别?
4.Java方法中的值传递机制
基本数据类型变量:引用数据类型变量:形参和实参:方法的封装时使用的是形参,调用时是实参
5.return关键字的使用
6.递归
7.可变个数形参的方法,调用方法与数组一致
面向对象特征之一:封装 1.概述为什么要封装?疯转的作用和含义?
我要用洗衣机,只需要按一下开关和洗涤模式局可以了。没有必要了解洗衣机的内部结构、了解电动机的原理。
开车—
程序设计追求“高内聚、低耦合”。
高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
低耦合:仅对外暴露少量的方法用于使用
3.隐藏对象内部的复杂性,支队挖公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。就是该藏的藏、该露的露。这就是封装性的设计思想。
当我们创建一个类的对象后,我们可以通过“对象的.属性”的方式,对对象的属性进行复制。这里赋值操作要受到属性的数据类型和存储范围的制约加入额外的限制条件。这个条件就不能在属性声明是体现,我们只能通过方法进行限制条件的添加。比如(set同时我们需要避免面用户再使用“对象的.属性”的方法对属性进行赋值。则需要将属性声明为私有的额(private)–>此时,针对于属性就体现了封装)
package OOP.AnimalText;
//创建一个类,当使用此类时,保证属性的值都在合理范围内
public class AnimalText {
public static void main(String[] args) {
Animal p1 = new Animal();
p1.variety = "human";
p1.setHeight(168);
p1.setLegs(2);
p1.show();//打印属性
}
}
class Animal {
String variety;
private int legs;
private double height;
private int age;
public void setLegs(int l){
if (l>0 && l%2==0){
legs =l ;
}else {
legs =0;
}
}
public void setHeight(int h){
if (h>0){
height =h ;
}else {
height =0;
}
}
public int getAge(){
return age;
}
//打印属性
public void show(){
System.out.println("variety:"+variety+"tage:"+legs+"theight:"+height+"tage:"+age);
}
}
3.封装的体现
我们将类的属性xxx私有化(private),同事,提供公共的(public)方法来获取(getXxx)和设置(setXxx)不对外暴露的私有的方法单例模式… 4.封装性的体现需要权限修饰符来配合
- Java规定的4中权限(从小到大):private、缺省、protected、public
package Order.O1;
public class Order2 {
public static void main(String[] args) {
Order1 o1 = new Order1();
//public可以在本项目的所有类中使用
o1.orderPublic = 1;
//protected可以在不同包的子类中使用
o1.orderProtected = 2;
//缺省可以在本包下的所有类中使用
o1.orderDefault = 3;
//private只能在本类中使用
//o1.orderPrivate = 4;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hlrOEYx8-1644334828457)(C:UserslinAppDataRoamingTyporatypora-user-imagesimage-20220118205302470.png)]
- 4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类只有public和缺省可以用来修饰类(非内部类)
java提供了四种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构权限的大小
创建一个Person类,定义一个私有属性age,使用set和get方法来体会封装
package OOP.Person;
public class PersonText {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(26);
System.out.println("age:"+p1.getAge());
}
}
class Person {
private int age;
public void setAge(int a) {
if (a>=0 && a<=130){
this.age = a;
}else {
throw new RuntimeException("输入数据非法!");
}
}
public int getAge() {
return age;
}
}
类的成员三:构造器(构造方法)
一、构造器的作用
创建对象
Person p1 = new Person();//后面的这个Person()就是Person类中的构造器
初始化对象的属性
public class PersonText {
public static void main(String[] args) {
Person person = new Person("Tom");
}
}
class Person {
String name;
int age;
//调用该类时初始化显示一些内容
public Person(){
System.out.println("Person()");
}
//初始化对象属性的构造器
public Person(String n){
name = n;
}
}
- 如果没有显式的构造器的话,系统默认提供一个空参构造器定义构造器的方法:权限修饰符 类名(形参){//方法体}一个类中可以存在多个构造器,就是构造器的重载构造器和方法的异同
不同:声明方式不同相同:都可以进行重载 一旦我们显式的定义了类的构造器之后,系统就不会再提供空参构造器(一旦挣钱,就不给低保了)一个类中,至少存在一个构造器
- 在Person类中添加构造器,利用构造器设置所有人的age属性初始值都为18。
package OOP.Person;
public class PersonText {
public static void main(String[] args) {
Person p1 = new Person();
System.out.println(p1.getAge());
}
}
class Person {
String name;
private int age;
public Person(){
age = 18;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
- 修改上题中的类和构造器,增加name属性,使得每次创建Person对象时初始化对象的age和name
package OOP.Person;
public class PersonText {
public static void main(String[] args) {
Person p1 = new Person("小林",25);
System.out.println("name:"+p1.getName()+"tage:"+p1.getAge());
}
}
class Person {
String name;
private int age;
public Person(String n,int a){
name = n;
age = a;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public Person(){
}
}
- 编写两个类,TriAngle和TriAngleText,其中TriAngle类中声明私有的边长base和高height,同事声明公告的方法访问私有变量,提供类必要的构造器。另一个类中使用这些公共方法,计算三角形的面积
package OOP.TriAngle;
public class TriAngleText{
public static void main(String[] args) {
TriAngle t1 = new TriAngle();
t1.setbase(5.1);
t1.setHeight(5.2);
System.out.println("base:"+ t1.getbase()+"tHeight:"+ t1.getHeight()+"tArea:"+ t1.getArea());
}
}
class TriAngle {
private double base;
private double height;
public TriAngle(double b,double h){
base = b;
height = h;
}
public TriAngle(){
}
public double getbase() {
return base;
}
public void setbase(double base) {
this.base = base;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getArea(){
return base*height;
}
}
- 定义Student类,
- 有四个属性:String name; int age; String school; String major;三个构造器:
- 第一个构造器Student(String n, int a)设置类的name和age;第二个构造器Student(String n, int a,String s)设置类的name、age和school;第三个构造器Student(String n, int a,String s,String m)设置类的name、age、school和major属性;
类中属性赋值的顺序:默认初始化–>显式初始化–>构造器赋值–>通过“对象.方法”或者“对象.属性”进行赋值前面三个赋值都只执行一次,可以叫初始化,后面的可以多次反复执行默认构造器的权限与类的权限一致在一个类中创建另一个类类型的属性,这叫做关联 JavaBean–拓展知识
JavaBean是一种Java语言写成的可重用组件所谓JavaBean,是指符合如下标准的Java类:
类是公告的有一个无参的构造器有属性,且有对应的get、set方法 用户可以使用JavaBean将功能、处理、值、数据库访问和其他的任何可以使用Java代码创造的对象进行打包,并且其他的开发者可以通过JSP页面、Servlet、其他的JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变 this关键字的使用 this是什么?
在Java中,this关键字比较难立即,它的作用和其词义很接近。
它在方法内部使用,即这个方法所属对象的引用;它在构造器内部使用,表示该构造器正在初始化的对象 this表示当前正在创造的对象,可以调用类的属性、方法和构造器什么时候使用this关键字呢?
当在方法内需要调用到该方法的对象是,就用“this.属性”或“this.方法”。但在大部分情况下,我们都选择省略“this.”。如果方的的形参与类的属性同名时,我们必须显式的使用“this.变量”的方式,表明此变量是属性,而非形参。具体的:我们可以使用this来区分局部变量和属性。比如:this.name=name this调用构造器
我们在类的构造器中,可以显式的使用“this(形参列表)”方法,调用本类中制定的其他构造器构造器中不能通过“this(形参列表)”方式调用自己如果一个类中有n个构造器,则最多有n-1构造器中使用了“this(形参列表)”规定:“this(形参列表)”必须声明在当前构造器的首行构造器内部,最多只能声明一个“this(形参列表)”,用来调用其他的构造器 练习一复习 简易银行
package OOP.BankText;
public class BankText {
public static void main(String[] args) {
Bank bank = new Bank();
bank.addCustomer("Jane","Smith");
bank.getCustomer(0).setAccount(new Account(2000));
bank.getCustomer(0).getAccount().withdraw(500);
System.out.println("客户:"+bank.getCustomer(0).getFirstName()+","+
bank.getCustomer(0).getLastName()+",余额为:"+
bank.getCustomer(0).getAccount().getBalance());
System.out.println("***********************");
bank.addCustomer("狗蛋","小");
System.out.println("银行现在的客户数量为:"+bank.getNumberOfCustomer());
}
}
class Bank {
private Customer[] customers;
private int numberOfCustomer;
public Bank(){
customers = new Customer[10];
}
public void addCustomer(String f,String l){
customers[numberOfCustomer++] = new Customer(f,l);
}
public int getNumberOfCustomer() {
return numberOfCustomer;
}
public Customer getCustomer(int index){
if (index >=0 && index 0){
balance+=amt;
System.out.println("成功存入:"+amt+"!");
}
}
public void withdraw(double amt){
if (amt>0 && amt <= balance){
balance-=amt;
System.out.println("成功取出:"+amt+"!");
return;
}
System.out.println("取款失败:余额不足!");
}
}
项目二:客户信息管理软件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RPWIGbt6-1644334828457)(C:UserslinAppDataRoamingTyporatypora-user-imagesimage-20220123151528541.png)]
添加用户,删除用户,修改用户信息,查询用户信息
面向对象(中) 面向对象特征二:继承性(inhertance) 一:继承性的好处:(Why?)减少代码的冗余,提高代码的复用性便于功能的扩展为了以后多态的使用提供了前提 二:继承性的格式:class A extends B{}
A:子类、派生类、subclassB:父类、超类、基类、superclass
2.1 体现:子类A一旦继承到父类B之后,子类会获得父类所有的属性和方法
特别的,父类结构中声明的private属性和方法,子类继承父类后,任然认为获取了父类中私有的结构
只是因为封装性的影响,子类不能直接调用父类中private的结构2.2 子类继承父类后,可以声明自己的属性和方法,实现功能的扩展。
子类和父类的关系,不同于集合与子集的关系
extends:扩展、延展
三:Java中关于继承性的一些规定- 一个类可以允许多个子类继承。Java中类的单继承性:一个子类只能有一个父类。(C++中可以多继承)子类是相对概念子类直接继承的父类叫直接父类,间接继承的类叫间接父类子类继承父类后,也继承了所有间接父类的结构
- 所有的类都继承与java.lang.Object(除了它本身)类意味着所有的类都具有java.lang.Object声明的功能
1.为什么要有类的继承性?(继承性的好处)
- 减少代码的冗余,提高代码的复用性便于功能的扩展为之后多态性的使用,提供了前提
2.继承性的格式
class A extends B{}
3.子类继承父类以后有哪些不同?
子类继承父类后拥有父类的所有属性和方法子类可以声明属性及方法实现功能的扩展子类可以通过父类提供的public方法使用父类private的结构
4.java.lang.Object类的理解
所有的类都继承与java.lang.Object(除了它本身)类
public void deposit(double amt){
if (amt > 0){
balance+=amt;
System.out.println(“成功存入:”+amt+"!");
}
}
public void withdraw(double amt){
if (amt>0 && amt <= balance){
balance-=amt;
System.out.println(“成功取出:”+amt+"!");
return;
}
System.out.println(“取款失败:余额不足!”);
}
}
## 项目二:客户信息管理软件
[外链图片转存中...(img-RPWIGbt6-1644334828457)]
添加用户,删除用户,修改用户信息,查询用户信息
# 面向对象(中)
## 面向对象特征二:继承性(inhertance)
### 一:继承性的好处:(Why?)
- 减少代码的冗余,提高代码的复用性
- 便于功能的扩展
- 为了以后多态的使用提供了前提
### 二:继承性的格式:class A extends B{}
- A:子类、派生类、subclass
- B:父类、超类、基类、superclass
- 2.1 体现:子类A一旦继承到父类B之后,子类会获得父类所有的属性和方法
特别的,父类结构中声明的private属性和方法,子类继承父类后,任然认为获取了父类中私有的结构
只是因为封装性的影响,子类不能直接调用父类中private的结构
- 2.2 子类继承父类后,可以声明自己的属性和方法,实现功能的扩展。
子类和父类的关系,不同于集合与子集的关系
extends:扩展、延展
### 三:Java中关于继承性的一些规定
1. 一个类可以允许多个子类继承。
2. Java中类的单继承性:一个子类只能有一个父类。(C++中可以多继承)
3. 子类是相对概念
4. 子类直接继承的父类叫直接父类,间接继承的类叫间接父类
5. 子类继承父类后,也继承了所有间接父类的结构
### 四
1. 所有的类都继承与java.lang.Object(除了它本身)类
2. 意味着所有的类都具有java.lang.Object声明的功能
### 继承性的复习
1.为什么要有类的继承性?(继承性的好处)
1. 减少代码的冗余,提高代码的复用性
2. 便于功能的扩展
3. 为之后多态性的使用,提供了前提
2.继承性的格式
- class A extends B{}
3.子类继承父类以后有哪些不同?
- 子类继承父类后拥有父类的所有属性和方法
- 子类可以声明属性及方法实现功能的扩展
- 子类可以通过父类提供的public方法使用父类private的结构
4.java.lang.Object类的理解
- 所有的类都继承与java.lang.Object(除了它本身)类
- 意味着所有的类都具有java.lang.Object声明的功能



