尚硅谷Java学习笔记-基础部分-3

前言
记录没有条理性,记一些自己没怎么用过,但是比较重要的内容。所以不是那么全面。
因为自己有一些java基础,为秋招准备的。大家看看就好,有错误的地方欢迎指正。

本节内容,面向对象(上)原片P176,比如属性方法,封装,构造器,关键字等。

一、类和对象

学习路线:

  • Java类及类的成员:属性、方法、构造器;代码块、内部类
  • 面向对象的大特征:封装性、继承性、多态性、(抽象性)
  • 其它关键字:this、super、static、final、abstract、interface、package、import等

1、理解面向对象

面向对象的流程,创建类 -> new出对象 -> 对象使用类的属性和方法。在Eclipse中新建Java Project-day08,在其下新建Package-com.atguigu.java,在其下新建Class-PersonTest

package com.atguigu.java;

public class PersonTest {
	public static void main(String[] args) {
		Person p1 = new Person(); //创建Person类的对象
		
		//属性赋值,属性调用
		p1.name = "Tom"; //未赋值的话输出null
		p1.isMale = true; //未赋值的话输出false
		System.out.println(p1.name);
		
		//方法调用
		p1.eat();
		p1.sleep();
		p1.talk("Chinese");

	}
}

class Person{  //类后面不带括号,而new时后面有括号,因为是构造器
	
	//属性
	String name;
	int age = 1;
	boolean isMale;
	
	//方法
	public void eat() { //方法后面带括号
		System.out.println("吃");
	}
	
	public void sleep() {
		System.out.println("睡");
	}
	
	public void talk(String language) { //传参
		System.out.println("说," + language);
	}
}
  • 多个对象之间,类似于简历模板,你填入的信息和我填入的信息不同,我修改我的属性对你没有影响。下述类似于arr2=arr1。将p1对象地址赋值给p3,改动p1的值和改动p3的值都会改变在堆中的值。
Person p1 = new Person();
Person p2 = new Person();
Person p3 = p1;
  • 对象的内存解析
    在这里插入图片描述
  • 补充:关于堆栈空间:局部变量在栈空间,new出来的在堆空间。对象的属性(非static)加载在堆空间中。其实还有一个区域,方法区,存放类的加载信息,常量池和静态域。
  • 匿名对象:创建的对象,没有显式得赋值给一个变量值,只能调用一次。
//匿名对象的使用
PhoneMall mall = new PhoneMall();
mall.show(new Phone()); 
//这里传入phone的实例化到phonemall中的show,相当于简化中间步骤,没有通过命名phone对象,直接作为形参传入show中

class PhoneMall{
	public void show(Phone phone){
		phone.sendEmail();
		phone.playGame();
	}
	
}
class Phone{...}
  • 补充:涉及到java语言与前端html、后端数据库交互时,前后端的结构在java层面交互时,都体现为类和对象。

2、对象数组

在这里插入图片描述
代码见上图右上角,右下角为Student类。先是Student[] stus = new Student[5];,表示在栈空间中定义了stus对象,是个Student数组类型。在堆空间里new了一个数组,大小为5。

  • 相比于之前实例化对象Student stu = new Student();只是单个对象
  • 多个放到数组里实例化Student[] stus = new Student[5],注意格式。

这个时候,如上图,只有栈空间的地址和堆空间的五个内存位置。因为没有赋值,所以是null(引用型变量,想不通就想想string是什么样子,怎么new的)。

下一步代码stus[0]=new Student();,如前所述,new出来的东西都是在堆空间中,且引用数据类型中存的要么null,要么地址值。所以stus[0]中存放的是新的地址值,默认属性值为0。

3、关于属性

属性和局部变量的区别

属性局部变量
位置类定义的{}中方法内,方法形参,代码块内,构造器内,构造器形参
权限修饰符封装性:private,public,缺省(默认),protected
默认初始值0,0.0,0-char,false,null-引用型无,要赋值
内存中堆空间(非static)栈空间

二、关于方法

方法:权限符 返回类型 方法名(形参列表) : public void eat(int m){...}
如果有需要返回值,就return xx;,如果是void,就不写或者return;

1、方法的重载

同一个类中,可以有多个同名方法,只要其参数个数或者类型不同即可。
(注意,定义一个方法时,有四个要素。权限+返回值类型+方法名称+输入形参,重载只肖名称相同,参数个数或类型不同耳,与返回类型等无关
比如:Arrays中的sort,binarySearch;printstream中的println。输入的参数不同,显示的结果不同,如下图。在这里插入图片描述
也或者自定义

package com.atguigu.java;
//对两个方法进行了重载。注意到在使用的时候,main为代码入口,先是把class自己实例化再使用。
public class OverLoad {
	public static void main(String[] args) {
		OverLoad ol = new OverLoad();
		ol.mOL(12,13); 
		//mOL(12,13)如果不实例化直接用的话,需要将所有的重载方法(函数)前面加上static。
		System.out.println(ol.max(1,2,3));
	}
	public void mOL(int i) {
		System.out.println(i*i);
	}
	public void mOL(int i,int j) {
		System.out.println(i*j);
	}
	public void mOL(String s) {
		System.out.println(s);
	}
	
	public int max(int i,int j) {
		return (i>j)?i:j;
	}
	public double max(double d1,double d2) {
		return (d1>d2)?d1:d2;
	}
	public double max(double d1,double d2,double d3) {
		double max = (d1>d2)?d1:d2;
		return (max>d3)?max:d3;
	}
}

2、可变个数的形参

可变个数形参的格式:数据类型 … 变量名。当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个。。。

public void show(int i){	
}
public void show(String s){
	System.out.println("show(String)");
}
public void show(String ... strs){ //可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载  //且要放在最后
	System.out.println("show(String ... strs)");
	for(int i = 0;i < strs.length;i++){
		System.out.println(strs[i]);
	}
}
//不能与上一个方法同时存在
public void show(String[] strs){ //可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
}

//调用
test.show("hello")
test.show(new String[]{"A","B","C"});

3、值传递机制

方法内变量的赋值:
如果变量是基本数据类型,赋值的是变量保存的值;
如果变量是引用数据类型,赋值的是变量保存的数据的地址值。

int m = 10; //在栈空间中有个变量m,里面有10
int n = m; //在栈空间中又有一个变量n,把10赋值到n中
n = 20;
		
Order o1 = new Order();
o1.orderId = 1001;
Order o2 = o1;//赋值以后,o1和o2的地址值相同,都指向了堆空间中同一个对象实体。
o2.orderId = 1002; //相应的o1的对象的属性也改了

交换函数swap,实参给swap形参传参,内部也交换了,但是swap结束后,mn仍为之前的数值,交换的结果没有传递出来。所以参数传递不能是基本数据类型。 要用的话只能用引用类型调用或者在方法前加上static,静态方法只能调用静态方法。 而引用调用传给形参的是地址,所以改动之后,出了函数交换依然生效。

package com.atguigu.java;

public class ValueTransfer {
	public static void main(String[] args) {
		int m=10;
		int n=20;
		System.out.println("原来m="+m+" "+"n="+n); //10 20
		
//		int temp = m;
//		m = n;
//		n = temp;
//		System.out.println("m="+m+" "+"n="+n); //20 10,直接在栈中进行交换。
		
		//基本数据类型的值传递
		ValueTransfer v = new ValueTransfer(); //自己类实例化自己
		v.swap(m, n);  //该方法结束后,栈空间里swap区域中的m,n,temp都弹出栈,只剩下main中原本的mn
		System.out.println("基本值传递swap方法外m="+m+" "+"n="+n); //10 20,说明没有对main区域中的mn发生变幻,只是mn副本互换,且已经出栈了。	
	
		//引用数据类型的值传递
		Data data = new Data();
		data.m=10;
		data.n=20;
		v.swap(data);//此时传进去的参数data是地址值,对应堆空间中的实体
		//传过来的形参-data副本(存的堆中实体地址值)也出栈,原来的data保留,依然指向堆中实体
		System.out.println("引用值传递swap方法外m="+data.m+ " " + "n="+data.n);
	}
	
	public void swap(int m,int n) { //在栈空间中有swap区域,有另外的mn,和之前的不同,在本方法中mn两者互换
		int temp = m;
		m = n;
		n = temp;
		System.out.println("基本值传递swap方法内m="+m+" "+"n="+n); //20 10,两者交换
	}
	
	public void swap(Data data) {
		int temp = data.m; //temp在栈空间中,函数结束,temp出栈
		data.m = data.n;
		data.n = temp;
		System.out.println("引用值传递swap方法内m="+data.m+ " " + "n="+data.n);
	}
}

class Data{
	int m;
	int n;
}

/*
原来m=10 n=20
基本值传递swap方法内m=20 n=10
基本值传递swap方法外m=10 n=20
引用值传递swap方法内m=20 n=10
引用值传递swap方法外m=20 n=10
*/

4、递归

方法自己调自己,要向已知方向递归(出口)。斐波那契,汉诺塔,快排。

三、封装性

追求:高内聚,低耦合。该隐藏的隐藏起来,该暴露的暴露出来。

1、代码体现

  • 属性:类的属性私有化private,提供set和get方法public。
    将类中的属性设置为private,需要改变属性,就使用setxxx(不像以前直接a.age=1这样直接赋值)。对于有特殊格式要求的输入,就在setxxx中定义ifelse,保证输入的合法。
private double radius;
public void setRadius(double radius){
	this.radius = radius;
}
public double getRadius(){
	return radius;
}
  • 方法:不对外暴露私有的方法,只供类内部使用
  • 单例模式,将构造器私有化
  • 如果不希望类在包外调用(这里包,是若干java文件在同一包下),可以使用缺省值。

2、四种权限修饰符

private<缺省<protected<public**
在这里插入图片描述
修饰类的内部-属性,方法,构造器,内部类:四种都可以
修饰类自己:只能用缺省和public,即private class xxx不合法。也即这个类要么包外能用要么不能。举例如下。

//文件1.Order.java
package com.atguigu.java;

public class Order { //类的权限只有public和缺省,public的权限只有一个,并且要与文件名一致
	//定义了3个属性,不同权限	
	private int orderPrivate;
	int orderDefault;
	public int orderPublic;
	
	//定义了3个方法,不同权限
	private void methodPrivate(){
		orderPrivate = 1;  //在类中,以下属性都可以访问
		orderDefault = 2;
		orderPublic = 3;
	}
	void methodDefault(){
		orderPrivate = 1;
		orderDefault = 2;
		orderPublic = 3;
	}
	public void methodPublic(){
		orderPrivate = 1;
		orderDefault = 2;
		orderPublic = 3;
	}
}
//同一个包下的不同文件OrderTest.java
package com.atguigu.java;

public class OrderTest {
	public static void main(String[] args) {
		
		Order order = new Order();
		
		order.orderDefault = 1;
		order.orderPublic = 2;
		//出了Order类之后,私有的结构就不可以调用了
//		order.orderPrivate = 3;//The field Order.orderPrivate is not visible
		
		
		
		order.methodDefault();
		order.methodPublic();
		//出了Order类之后,私有的结构就不可以调用了
//		order.methodPrivate();//The method methodPrivate() from the type Order is not visible
	}
}
//不同包下的java文件OrderTest.java
package com.atguigu.java1;

import com.atguigu.java.Order;

public class OrderTest {
	public static void main(String[] args) {
		Order order = new Order();

		order.orderPublic = 2;
		// 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
//		order.orderDefault = 1;
		// order.orderPrivate = 3;//The field Order.orderPrivate is not visible

		order.methodPublic();
		// 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
//		order.methodDefault();
		// order.methodPrivate();//The method methodPrivate() from the type Order is not visible
	}
}

四、构造器

1、作用:创建对象,初始化对象信息,名称和类名相同。

class Person{
	public Person(){}
	public Person(String n){name = n;}//构造器的同时初始化了
	public Person(String n,int a){
		name = n;
		age = a;
	}
}
  • 说明:未显式定义的话,系统默认提供一个空参的构造器;多个构造器可构成重载;如果显式定义的话,系统不再默认提供空参构造器了,需要自己补上了,再写其他的构造器。
  • 构造器的使用举例,所以当属性为private时,改变属性的值两种办法,一种构造器传参时,一种setget方法间接访问属性。
package com.atguigu.exer1;
/*
 * 编写两个类,TriAngle和TriAngleTest,其中TriAngle类中声明私有的底边长base和高height,同时声明公共方法访问私有变量。
 * 此外,提供类必要的构造器。另一个类中使用这些公共方法,计算三角形的面积。
 */
public class TriAngle { 
	private double base;//底边长
	private double height;//高
	
	//两个构造器
	public TriAngle(){
		
	}
	public TriAngle(double b,double h){
		base = b;
		height = h;
	}
	//封装性
	public void setBase(double b){
		base = b;
	}
	public double getBase(){
		return base;
	}
	public void setHeight(double h){
		height = h;
	}
	public double getHeight(){
		return height;
	}
	
}

2、属性赋值顺序

默认初始化 - 显式初始化int age=2- 构造器中初始化 - 对象.方法or对象.属性

3、JavaBean

是一种java类:公共的,有一个无参的公共构造器,有属性,且有对应的setget方法。如下图。mysql中的一些字段(列)可以作为java中类的属性,并有setget方法。空参构造器是使用反射的方式构造对象。

public class Customer {
	
	private int id;
	private String name;
	
	public Customer(){
		
	}
	
	public void setId(int i){
		id = i;
	}
	public int getId(){
		return id;
	}
	public void setName(String n){
		name = n;
	}
	public String getName(){
		return name;
	}
	
}

4、UML图

banking为包名
在这里插入图片描述

五、关键字

1、this

  • 理解为当前对象(不是当前类)。修饰属性,方法,构造器
  • 平时省略,当传入的形参和属性重名时,为区分,才需要用this
//类中有属性,构造器和方法
class Person{
	private String name;
	private int age;
	
	//构造器4个
	public Person(){...} //空参不代表方法中也是空的,也可以有一些功能,比如这里输出print。
	//注意这里书写,没有public void Person等,直接public Person没有返回类型。
	public Person(String name){
		this(); 
		this.name = name; //形参与属性重名时,为区分,使用this,前者属性值,后者传入的形参
	public Person(int age){
		this();
		this.age = age;
	}	
	public Person(String name,int age){
		this(age);
		this.name=name;
	
	//存取属性值的方法
	public void setName(String name){
		this.name = name; //传入的形参
	}
	public String getName(){
		return this.name; //返回的属性
	}
	public void setAge(int age){
		this.age = age;
	}
	public int getAge(){
		return this.age;
	}
	
	//常见方法
	public void eat(){
		...
		this.study();//this调用方法
	}
	public void study(){
		...
	}
}

2、package

每“.”一次,就代表一层文件目录
同一个包下,不能有同名的类和接口。不同的包下可以。
书写,请看文件中代码第一行package com.atguigu.exer1;
在这里插入图片描述

3、import

  • 可以用xxx.*表示包下的所有类。
  • java.lang包下的类或者接口不用再导入了,默认就可以用,比如String。
  • 当前包下的不同文件java,也不需要导入,直接实例化对象也可。
  • 如果本包下有个文件class,和另外一个包的文件class,都想调用,但是重名,就使用全类名方式显示。
  • import只包含该包下的接口和类,但是也只是平行并列的,不会再找下一级子包。包的子包不包含,还是需要导入的。
  • import static:import导包,而import static导包下类的属性或者方法
package com.atguigu.java2;

import java.lang.reflect.Field;
import java.util.*;

import com.atguigu.exer4.Account;
import com.atguigu.exer4.Bank;
import com.atguigu.java2.java3.Dog; //包中包还是需要把全部名称展示出来

import static java.lang.System.*;
import static java.lang.Math.*;

public class PackageImportTest {
	public static void main(String[] args) {
		
		String info = Arrays.toString(new int[]{1,2,3});
		
		Bank bank = new Bank();
		
		ArrayList list = new ArrayList();
		HashMap map = new HashMap();
		
		Scanner s = null;
		
		System.out.println("hello!");
		
		Person p = new Person();
		
		Account acct = new Account(1000); //exer4中的account
		//全类名的方式显示
		com.atguigu.exer3.Account acct1 = new com.atguigu.exer3.Account(1000,2000,0.0123);
		
		Date date = new Date();
		java.sql.Date date1 = new java.sql.Date(5243523532535L);
		
		Dog dog = new Dog();
		
		Field field = null;
		
		out.println("hello");
		
		long num = round(123.434);
	}
}

六、设计模式

MVC:model view control
将程序分开:输入输出,数据处理,数据展示。model模型层处理数据,controller处理业务逻辑,view显示数据。

文王拘而演《周易》,仲尼扼而作《春秋》。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页