目录
类与对象
类class
对象
修饰符private
this关键字
构造函数
继承
权限修饰符
包package
状态修饰符final
类与对象
类
- 类是对现实生活中一类事物的抽象,里面包含了这类事物共有的属性(名词)和行为(动词)
- 例如人类,人就是一个大类,每个人都应该有名字,年龄,性别,身高,体重(这些都是属性)...,当然每个人还可以说话,走路,跑步(这些都是行为)...
对象
- 而对象则是看得见,摸得着,实实在在的实体
- 实例化类,就可以得到一个具体的对象
类与对象的关系
- 类是对象的抽象,对象是类的实体
- 一个类可以实例化n多个对象
简单理解:类是对事物的一种描述,对象则是具体存在的事物
类class
- 类是Java程序的基本组成单位
- 类是具有相同属性和行为的一组对象的集合
- 属性:类中方法外的变量(类中通过成员变量来体现)
- 行为:类中的方法
举例:定义一个手机类
- 成员:表示类中的成员,可以是成员属性,也可以是成员方法
- 成员属性可以不用赋值,默认系统会赋一个默认值
public class Phone {
// 属性(成员属性)
String brand; // 品牌
double price; // 价格
String color; // 颜色
// 方法(成员方法)
public void call() {
System.out.println("手机都可以打电话");
}
public void sendMessage() {
System.out.println("手机都可以发短信");
}
}
对象
创建对象
类名 对象名 = new 类名();
使用成员属性和成员方法
对象名.成员属性 对象名.成员方法
举例:
public class Phone {
// 属性(成员属性)
String brand; // 品牌
double price; // 价格
String color; // 颜色
// 方法(成员方法)
public void call() {
System.out.println("手机都可以打电话");
}
public void sendMessage() {
System.out.println("手机都可以发短信");
}
// 主方法,程序入口
public static void main(String[] args) {
// 实例化类,创建一个具体的对象
Phone phone = new Phone();
// 访问成员属性
phone.brand = "华为";
phone.price = 6999.00;
phone.color = "远峰蓝";
// 访问成员方法
phone.call();
phone.sendMessage();
}
}
成员变量与局部变量的区别
- 成员变量:类中方法外的变量,就是成员变量
- 局部变量:类中方法内的变量,就是局部变量,参数也是局部变量
public class Phone {
// 属性(成员属性,又叫成员变量)
String brand; // 品牌
double price; // 价格
String color; // 颜色
// 方法(成员方法)
public void call() {
String inner = "局部变量"; // 局部变量
System.out.println("手机都可以打电话");
System.out.println("变量声明在方法内,这是局部变量" + inner);
}
public void sendMessage(String msg) { // 参数也是局部变量
System.out.println("手机都可以发短信,短信内容为" + msg);
}
}
具体区别:
区别 | 成员变量 | 局部变量 |
类中位置不同 | 类中方法外 | 类中方法内 |
内存中位置不同 | 堆内存 | 栈内存 |
声明周期不同 | 随对象存在而存在,随对象消失而销毁 | 随方法调用而存在,随方法结束消失而消失 |
初始化值不同 | 有默认的初始化值 | 没有默认的初始化值,必须定义的时候赋值 |
修饰符private
- 是一个权限修饰符,表示私有的
- 可以修饰成员变量和成员方法
- 被private修饰的成员变量/方法,就只能在本类中进行使用。可以保护成员变/方法不被其他类使用
定义私有成员
修饰成员变量
private 数据类型 成员变量名;
修饰成员方法
private 方法返回值类型 成员方法名(参数...) { ... }
举例:
- void表示方法没有返回值。如果方法需要有返回值,则void处就写对象的返回值类型即可
public class Phone {
// 属性(成员属性,又叫成员变量)
private String brand; // 品牌
private double price; // 价格
private String color; // 颜色
// 方法(成员方法)
private void call() {
System.out.println("手机都可以打电话");
}
}
访问private修饰的(访问私有变量)
- 如果在本类中,可以直接访问
- 如果是外部类,需要通过get和set进行访问
手机类
public class Phone {
// 属性(成员属性,又叫成员变量)
private String brand; // 品牌
private double price; // 价格
private String color; // 颜色
// 方法(成员方法)
private void call() {
System.out.println(brand + "手机都可以打电话"); // 华为手机都可以打电话
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
手机测试类
public class Main {
public static void main(String[] args) {
// 实例化类
Phone phone = new Phone();
// 通过set方法,给成员变量赋值
phone.setBrand("华为");
// 通过get方法,获取成员变量
System.out.println(phone.getBrand()); // 华为
}
}
Iead编辑器有快捷键可以生成get和set方法
- 首先我们在类中声明好成员变量
- 然后空白处点击鼠标右键,找到Generate点击
- 最后根据需要点击生成对应的即可
this关键字
- 我们只需要记住,谁调用,this就是谁
- 一般this用来访问本类中的属性,方法,构造器
- this用于区分 成员 与 局部
- this只能在类定义的方法中使用,不能在类定义的外部使用
public class Phone {
private String brand;
private void call() {
System.out.println(brand + "手机都可以打电话");
}
public String getBrand() {
// 这里的brand表示当前类中的成员属性brand
return brand;
}
public void setBrand(String brand) {
// 这里的this就表示当前类的实例化的对象
// this.brand 表示当前类中的成员属性brand(成员变量)
// (如果参数没有与brand重名,则可以省略this,也表示当前类中的成员属性brand。可以看下getBrand方法)
// brand 则表示传入的参数brand(局部变量)
this.brand = brand;
}
}
访问成员变量
this.成员变量名
访问构造函数(先了解)
this(参数列表)
- 只能在构造器中使用(意思就是只能在构造器中访问另外一个构造器)
- 并且必须放在构造函数的第一条语句上,顶置
构造函数
- 构造函数分为有参构造函数和无参构造函数
- 如果不写,则会默认内置一个无参构造函数
- 如果写了有参构造函数,则不会默认提供无参构造函数,也就是说,要补一个无参构造函数
- 构造函数的方法名要与类名一致
- 作用:创建对象时,可以完成对成员属性的初始化(其实就是完成对数据的初始化)
- 实例化对象时,会先执行构造函数
- 如果实例化对象时,没有传入参数,则会调用无参构造函数,如果实例化对象时,传入了参数,则会调用有参构造函数
人类
package Person;
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private Person() {
System.out.println("我是无参构造函数");
}
public Person(String name, int age) {
// 可以对传入的参数进行下简单的判断
if (age > 120 | age < 0) {
System.out.println("您输入的年龄有误");
} else {
this.name = name;
this.age = age;
}
}
}
人类测试类
import Person.Person;
public class Main {
public static void main(String[] args) {
Person zs = new Person("张三", -1); // 您输入的年龄有误
}
}
修改成员变量的方式有两种
- 通过set方法进行修改,可以在其中进行一些简单的判断
- 也可以通过有参构造函数进行修改,也可以在其中进行一些简单的判断
继承
- 每个类只能继承一个父类
- 但是可以多层继承(爷 -> 父 -> 孙 -> 重孙...)
- 继承可以使子类具有父类的属性和方法,还可以在子类中声明自己的成员,对父类进行扩充
- 父类又称为超类,基类。子类又称派生类
- 子类中所有的构造方法,默认都会访问父类中的无参构造方法。先有父再有子
- 每个子类构造方法的第一句默认都是super() ,如果无参,则是super(),如果有参,则super(参数...)
- this() 表示调用本类的无参构造方法
- super() 表示调用父类的无参构造方法
public class 子类 extends 父类 { ...... }
父类
package Person;
public class Father {
private String name;
private String age;
public void doBusiness() {
System.out.println("做生意的");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Father() {
System.out.println("父类的无参构造函数");
}
public Father(String name, String age) {
System.out.println("父类的有参构造函数");
this.name = name;
this.age = age;
}
}
子类
package Person;
public class Son extends Father {
// 继承了父类,则可以直接使用父类的东西
public Son() {
super(); // 这个不用写,默认就内置了
System.out.println("子类的无参构造方法");
}
public Son(String name, String age) {
super(name, age);
System.out.println("子类的有参构造方法");
}
}
测试类
import Person.Son;
public class Main {
public static void main(String[] args) {
Son s = new Son(); // 父类的无参构造函数(会先执行父类的无参构造函数) 子类的无参构造方法
s.doBusiness(); // 做生意的
}
}
this与super
- this表示本类对象的引用
- super表示父类存储空间的标识(可以理解为父类对象的引用)
访问成员变量 | 访问成员方法 | 访问构造函数 | |
this | this.xxx | this.xx() | this() / this(参数...) |
super | super.xxx | super.xx() | super() / super(参数...) |
子类访问构造的顺序
- 如果子类实例化无参 父类无参 --> 子类无参
- 如果子类实例化有参 父类有参 --> 子类无参
父类子类跟上面一样
测试类
import Person.Son;
public class Main {
public static void main(String[] args) {
new Son(); // 父类的无参构造函数 子类的无参构造方法
new Son("张三","41"); // 父类的有参构造函数 子类的有参构造方法
}
}
子类方法重写
- 子类如果不满足父类的方法,也可以对父类中的方法进行重写或者补充
- 但是重写的方法,方法名和参数列表都需要跟父类的一致
- 重写需要添加 @Override 关键字,可以对重写进行检查
- 私有方法是不可以重写的,因为子类不会继承到父类的私有方法,所以更不可能重写.
- 子类方法的访问权限(public > default > private),不能比父类低
父类
package Person;
public class Father {
public void doBusiness() {
System.out.println("做生意的");
}
}
子类
package Person;
public class Son extends Father {
// 方法重写
@Override
public void doBusiness() {
super.doBusiness();
System.out.println("子类可以重写父类中的方法,也可以在原方法上进行扩展");
}
}
测试类
import Person.Son;
public class Main {
public static void main(String[] args) {
Son son = new Son();
son.doBusiness(); // 做生意的
}
}
权限修饰符
- 可以修饰方法,属性,类。一般都是放在最前面的
- 权限修饰符一共有4个,分别是(从大到小):public,protected,defaule,private
权限修饰符 | 同一个类 | 同一个包 | 不同包的子类 | 不同包的非子类 |
private | √ | × | × | × |
default | √ | √ | × | × |
protected | √ | √ | √(只有继承的,在不同包下才可以访问) | × |
public | √ | √ | √ | √ |
private
- 被private修饰的,都是私有成员。只能在本类中才能进行访问
package Person;
public class Father {
// 私有成员属性
private int num = 100;
// 私有的,只能在本类中进行使用
public void readPrivate() {
System.out.println("私有变量只能在本类中进行访问:" + num);
}
}
default
- 不写权限修饰符,默认就是这个。只能在本类和同一个包下的类进行使用
类A(Person包下)
package Person;
public class Father {
// 私有成员属性
int num = 100;
// 私有的,只能在本类中进行使用
public void readPrivate() {
System.out.println("默认变量可以在本类中进行访问:" + num);
}
}
类B(Person包下)
package Person;
public class Son {
public static void main(String[] args) {
Father father = new Father();
father.readPrivate();
father.num = 10;
System.out.println(father.num);
}
}
protected
- 受保护的,只能在本类中,同一个包下,如果不同包,但是有继承关系,这几种情况使用
类A(Person包下)
package Person;
public class Father {
// 受保护的成员属性
protected int num = 100;
// 可以在本类中进行使用
public void readPrivate() {
System.out.println("受保护成员变量可以在本类中进行访问:" + num);
}
}
类B(Person包下)
package Person;
public class Son {
public static void main(String[] args) {
Father father = new Father();
father.readPrivate();
// 同一个包下,受保护的成员也可以使用
father.num = 10;
System.out.println(father.num);
}
}
类C(Demo包下)
package Demo;
import Person.Father;
public class Demo extends Father {
public void print() {
System.out.println("父类的受保护成员变量为" + super.num);
}
}
测试类(Demo包下)
package Demo;
import Person.Father;
public class PersonTest {
public static void main(String[] args) {
// 1. 不同包下
Father father = new Father();
// 如果没有继承关系,是访问不了受保护的成员的
// father.num 编译会直接报错
// 2. 不同包下,但是有继承关系
Demo demo = new Demo();
demo.print();
}
}
public
- 都可以直接进行使用,权限放开
包package
- 包其实就是文件夹,作用就是对类进行分类管理
package 包名;
- 多级包,则用 . 进行分开
package 一级.二级....
举例:
package com.Xxx.xx
- 就是创建了一个com的文件下,里面有Xxx文件夹,Xxx文件夹下有一个xx的文件夹
类的名称
- 类完整名称 = 包的名称 + 类的名称 保障类名唯一,不允许重复
举例:
com.minsheng.day01
- 在此包下创建一个Demo的类,则此类的完整名称就是 com.minsheng.day01.Demo
导包
import com.minsheng.day01.* // 导入所有
import com.minsheng.day01.xxx // 导入具体的单一的类
- 如果在同一个包下,默认情况下,不需要写import
状态修饰符final
- final(最终态),可修饰类,成员变量,成员方法
- 被final关键字修饰的类,无法被继承
- 被final关键字修饰的成员方法,可以被继承,但是无法被重写
- 被final关键字修饰的成员变量,是无法被修改的,并且必须赋初始值。常量名称一般都大写
父类
// 被final修饰的类,是无法被继承的
public class Demo {
// 被final修饰的成员变量,是不能改变的,并且必须赋初始值。也是不能被继承的
private final int SUCCESSCODE = 200;
// 被final修饰的成员方法,可以被继承,但是无法被重写
public final void print() {
System.out.println("被final修饰的成员方法,是无法被重写的");
}
}
子类
public class Test extends Demo {
public void fn() {
super.print();
}
}
测试类
public class Main {
public static void main(String[] args) {
new Test().fn();
}
}
final还可以修饰局部变量
- 修饰基本数据类型:不能被修改,必须赋初始值
public class Demo {
public void print() {
// final修饰局部变量,这个局部变量就不可以被修改了,并且必须赋初始值
final int age = 24;
// age = 20; // Cannot assign a value to final variable 'age'
}
}
- 修饰复杂(又叫引用)数据类型:栈内存地址不能够发生改变,但是引用数据类型的内存地址里面的成员属性值是可以变化的
类A
public class Demo {
int age = 24;
}
测试类
public class Main {
public static void main(String[] args) {
// 被final修饰的复杂数据类型,内存地址不可以变,但是里面的成员变量可以改变
final Demo demo = new Demo();
// 改变成员变量
demo.age = 18;
System.out.println(demo.age);
}
}