类的成员有:属性、方法、构造器、代码块、内部类。
一. 类和对象的创建步骤
(1)创建类,设计类的成员(属性、方法);
(2)实例化类的对象(创建类的对象):类名 对象名 = new 类名;
(3)调用对象的属性(对象名 . 属性),调用对象的方法(对象 . 方法)
public class PersonTest {
public static void main(String[] args){
Person person1 = new Person(); //创建对象person1
person1.name = "Bob"; //调用对象person1的属性
person1.age = 22;
person1.weight = 123.5;
person1.height = 178.5;
person1.introduction(); //调用对象person1的方法
System.out.println("身高:"+ person1.height + "," + "体重:" + person1.weight);
//输出:姓名:Bob,年龄:22
// 身高:178.5,体重:123.5
Person person2 = new Person(); //创建对象person2
person2.name = "Joe"; //调用对象person2的属性
person2.age = 28;
person2.introduction(); //调用对象person2的属性
//输出:姓名:Joe,年龄:28
Person person3 = person1; //将对象person1的地址赋值给对象person3,导致person3和person1指向堆中的同一个对象实体
person3.introduction(); //姓名:Bob,年龄:22
System.out.println(person3.height); //178.5
person3.height = 180.2;
System.out.println(person1.height); //180.2
}
}
class Person{ //创建类
String name; //属性
int age;
double weight;
double height;
public void introduction(){ //方法
System.out.println("姓名:"+ name + ","+ "年龄:" + age);
}
}
匿名对象:匿名对象没有显示的赋给一个变量名,只能调用一次。
public class PersonTest {
public static void main(String[] args){
//匿名对象
new Person().show(); //introduce yourself
new Person().name = "Tom";
new Person().introduction(); //null,两个为不同的对象,所以name的值没有修改
}
}
class Person{
String name;
public void introduction(){
System.out.println(name);
}
public void show(){
System.out.println("introduce yourself");
}
}
二. (属性)成员变量和局部变量
成员变量:属性;
局部变量:声明在方法内的变量、方法的形参、构造器内的变量、构造器的形参、代码块内的变量。
相同点:(1)定义变量的格式都为:数据类型 变量名 = 变量值; (2)变量都必须先声明后使用。
不同点:声明属性时,可以使用权限修饰符指明其权限(权限修饰符有:private、protected、default、public);声明局部变量不可以使用权限修饰符。
public class PersonTest {
public static void main(String[] args){
Person person1 = new Person(); //创建对象person1
person1.name = "Bob"; //调用对象person1的属性
person1.age = 22;
person1.weight = 123.5;
person1.height = 178.5;
person1.introduction(); //调用对象person1的方法
System.out.println("身高:"+ person1.height + "," + "体重:" + person1.weight);
//输出:姓名:Bob,年龄:22
// 身高:178.5,体重:123.5
person1.speak("English");
person1.eat(); //
//输出:母语是:English
// 喜欢吃的食物是:bread
}
}
class Person{
String name; //属性(成员变量),可以不用赋值,如果在主函数中调用属性时也没有赋值,则会得到默认初始化值
public int age; //可以给成员变量指明权限
double weight;
double height;
public void introduction(){
System.out.println("姓名:"+ name + ","+ "年龄:" + age);
}
public void speak(String language){ //language是形参,是局部变量,在调用时需要给language赋值
System.out.println("母语是:" + language);
}
public void eat(){
String food = "bread"; //局部变量,必须赋值
System.out.println("喜欢吃的食物是:" + food);
}
}
三. 方法
方法的声明:权限修饰符 返回值类型 方法名(形参列表){ 方法体 } //形参可以有0个、1个、多个。
方法分为:(1)有返回值:必须在声明方法时,指定返回值的类型(int、double、String等),并且需要使用return关键字来返回指定类型的数据;(2)没有返回值:使用void。
public class PersonTest {
public static void main(String[] args){
Person person1 = new Person();
person1.introduction("Tom", 22); //姓名:Tom,年龄:22
person1.speak("English"); //母语是:English
person1.eat(); //喜欢吃的食物是:bread
System.out.println(person1.myNation("USA","New York")); //国籍:USA, 城市:New York
System.out.println(person1.myAppearance(185.5)); //身高:185.5
System.out.println(person1.Myweight()); //135.2
}
}
class Person{
double weight = 135.2;
//没有返回值
public void introduction(String name,int age){ //2个形参
System.out.println("姓名:"+ name + ","+ "年龄:" + age);
}
public void speak(String language){ //1个形参
System.out.println("母语是:" + language);
}
public void eat(){ //没有形参
String food = "bread"; //局部变量,必须赋值
System.out.println("喜欢吃的食物是:" + food);
}
//有返回值
public String myNation(String country,String city){ //2个形参
String from = "国籍:" + country + ", 城市:" + city;
return from;
}
public String myAppearance(double height){ //1个形参
String appearance = "身高:" + height;
return appearance;
}
public double Myweight(){ //没有形参
return weight;
}
}
方法重载:
在同一个类中,方法名相同,形参个数或者形参数据类型不同的方法构成重载。
判断是否构成重载:与方法的权限修饰符、返回值类型、方法体、形参名无关。
class Test{
//以下方法构成重载
//形参数据类型不同,构成重载 //与左侧没有构成重载(与返回值类型无关)
public void sum(int num1, int num2){ // public int sum(int num1, int num2){
System.out.println(num1 + num2); // return num1 + num2;
} // }
//与左侧没有构成重载(与权限无关)
public void sum(double num1, double num2){ // private void sum(double num1, double num2){
System.out.println(num1 + num2); // System.out.println(num1 + num2);
} // }
//与左侧没有构成重载(与形参名无关)
public void sum(String num1, int num2){ // public void sum(String a, int b){
System.out.println(num1 + num2); // System.out.println(a + b);
} // }
public void sum(int num1, String num2){
System.out.println(num1 + num2);
}
//形参个数不同,构成重载 //与左侧没有构成重载(与方法体无关)
public void sum(int num1){ //public void sum(int num1){
System.out.println(num1 + 2); // System.out.println(num1 + 3);
} //}
public void sum(double num1){
System.out.println(num1 + 2);
}
}
可变个数的形参(数据类型 ... 变量名):
可变个数形参的方法与本类中方法名相同、形参不同的方法构成重载。
import java.util.Arrays;
public class Test{
public static void main(String[] args) {
Test test = new Test();
test.showString(); //[]
test.showString("A"); //A
test.showString("A","B"); //[A,B]
test.showInt(1); //1
test.showInt(1,2); //[1,2]
test.show(13, "C","D"); //13,[C, D]
}
public void showString(String str){
System.out.println(str);
}
public void showString(String ... str){ //等价于public void showString(String[] str), str是数组
//System.out.println(str); //输出的是数组的地址
System.out.println(Arrays.toString(str));
}
public void showInt(int i){
System.out.println(i);
}
public void showInt(int ... i){ //i是数组
//System.out.println(str); //输出的是数组的地址
System.out.println(Arrays.toString(i));
}
public void show(int i, String ... str){ //在一个方法中,可变个数的形参必须在最后,且只能有一个
System.out.println(i + "," + Arrays.toString(str));
}
}
值传递:
如果形参是基本数据类型,此时实参赋值给形参的是实参存储的数据;
如果形参是引用数据类型,此时实参赋值给形参的是实参存储数据的地址;
public class Test{
public static void main(String[] args) {
Data data = new Data();
data.m = 3;
data.n = 4;
data.swap1(data.m, data.n);
System.out.println("m=" + data.m + ", n=" + data.n); //m=3, n=4 没有交换成功
data.swap2(data);
System.out.println("m=" + data.m + ", n=" + data.n); //m=4, n=3 交换成功
}
}
class Data{
int m;
int n;
public void swap1(int num1, int num2){
int temp = num1;
num1 = num2;
num2 = temp;
}
public void swap2(Data d){
int temp = d.m;
d.m = d.n;
d.n = temp;
}
}
四. 构造器
构造器的作用:(1)创建对象;(2)初始化对象的属性
如果没有显式的定义类的构造器,则系统会提供一个默认的空参构造器;
如果显示的定义了构造器,则系统就不会提供空参构造器,必须自己定义一个空参构造器;
一个类中至少有一个构造器
定义构造器:权限修饰符 类名(形参列表){ }
一个类中定义的多个构造器彼此构成重载
IDEA中生成构造器的快捷键:ALT + SHIFT + 0 (ALT + INSERT)
public class PersonTest {
public static void main(String[] args){
Person person1 = new Person(); //创建类的对象:new 构造器; 这里调用的是空参构造器1,如果没有,则系统会提供一个默认的空参构造器
Person perosn2 = new Person("Tom"); //调用构造器2
System.out.println(perosn2.name); //Tom
Person person3 = new Person("Tom",22); //调用构造器3
person3.introduction(); //姓名:Tom,年龄:22
}
}
class Person{
//属性
String name;
int age;
//构造器1
public Person(){
}
//构造器2
public Person(String n){
name = n;
}
//构造器3
public Person(String n, int a){
name = n;
age = a;
}
//方法
public void introduction(){
System.out.println("姓名:" + name + ",年龄:" + age);
}
}
五. this关键字
this可以修饰:属性、方法、构造器
使用this关键字调用属性和方法:
在类的方法和构造器中,可以使用 " this . 属性 " 或者 " this . 方法 " 来调用当前对象的属性和方法。
通常情况下省略this,如果方法的形参和属性同名时,必须显式的使用"this . 变量"来表明此变量是属性,而不是形参。
public class PersonTest {
public static void main(String[] args){
Person person1 = new Person();
Person perosn2 = new Person("Tom");
System.out.println(perosn2.name); //Tom
Person person3 = new Person("Tom",22);
System.out.println("姓名:" + person3.name + ", 年龄:" + person3.age); //姓名:Tom, 年龄:22
person3.high(182.5);
System.out.println(person3.height); //182.5
person3.sex = '男';
person3.introduction(); //姓名:Tom, 年龄:22
//性别:男
}
}
class Person{
//属性
String name;
int age;
double height;
char sex;
//构造器
public Person(){
}
public Person(String n){
name = n; //可以省略this.
}
public Person(String name, int age){
this.name = name; //当构造器的形参和属性同名时,必须使用this.(this.name指的是属性,name指的是形参)
this.age = age;
}
//方法
public void sexual(){
System.out.println("性别:" + sex);
}
public void high(double height){
this.height = height; //当方法的形参和属性同名时,必须使用this.
}
public void introduction(){
System.out.println("姓名:" + name + ", 年龄:" + age);
this.sexual(); //使用this.方法来调用其他方法,可以省去this.
}
}
使用this关键字调用构造器:
在类的构造器中,可以使用 " this(形参列表) " 的方式来调用本类中的其他构造器
构造器中不能使用 " this(形参列表) " 调自己
当在构造器中调用其他构造器时, " this(形参列表) "必须在首行,且构造器内部只能声明一个 " this(形参列表) "。
public class PersonTest {
public static void main(String[] args){
Person person = new Person("Tom",22);
//输出: 人
// 姓名:Tom, 年龄:22
}
}
class Person{
//属性
String name;
int age;
double height;
//构造器1
public Person(){
System.out.println("人");
}
//构造器2
public Person(int age){
this(); //调用构造器1
this.age = age;
}
//构造器3
public Person(String name, int age){
this(age); //调用构造器2
this.name = name;
System.out.println("姓名:" + name + ", 年龄:" + age);
}
}
六. 权限修饰符
权限修饰符 | 类内部 | 同一个包 | 不同包的子类 | 同一个工程 |
private | yes | |||
default | yes | yes | ||
protected | yes | yes | yes | |
public | yes | yes | yes | yes |
private、default、protected、public都可以用来修饰:属性、方法、构造器、内部类
修饰类只能用:default、public