this关键字
概述
this代表所在类的对象引用,即当前对象
new 创建出来的对象
调用方法的对象
作用
1、调用本类中的属性和方法(区别成员变量和局部变量)
2、调用本类中的其他构造方法:this()
格式:
this([参数...]);
会根据参数列表调用对应的构造方法
public Rabbit(String color) {
// 调用本来中的属性
this.color = color;
}
public Rabbit(String color, int age, double weight) {
// 调用本类中的其他构造方法
this(color);
this.age = age;
this.weight = weight;
}
【注意】
1、this()只能在构造方法中使用
2、this()只能在第一行
3、构造方法中不能同时出现两个this(),因为2
4、不能自己调用自己,不能相互调用
规范化this()
class Son {
String name;
int age;
float salary;
public Son() {
}
public Son(String name) {
// 调用Son(String name, int age, float salary)
this(name, 0, 0.0F);
}
public Son(String name, int age) {
// 调用Son(String name, int age, float salary)
this(name, age, 0.0F);
}
public Son(String name, int age, float salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
}
总结
- this表示的是当前对象
- this可以调用本类中的属性和方法,最常用于区分成员变量和局部变量
- this还可以调用本类中的构造方法,但是要注意有坑
访问(权限)修饰符
private(私有)关键字
1、可以修饰成员变量和成员方法
2、被private修饰的变量和方法仅本类中可用
3、被private修饰的变量需要提供get、set方法供类外调用使用
4、boolean类型的 get 方法比较特殊:
public boolean isName(String name){
return name;
}
public class Dog {
private String name;
int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
private void function() {
System.out.println("method be execute!");
}
public void executeFunction() {
this.function();
}
}
Java中的访问修饰符
类内部 | 同包下 | 子类中 | 非同包 | |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
默认不写 | √ | √ | × | × |
private | √ | × | × | × |
总结
1、一般我们最常用的就是private和public,建议任何情况下都使用访问修饰符对变量和方法进行限制
2、public权限最高,整个项目中都可以访问(同一个项目),private权限最小,只能在本类中使用
3、被private修饰的变量和方法可以通过提供公共的方法对其进行访问
super关键字
概述
super指父类对象,用来区分父类和子类,用于调用父类的属性和方法
用法和this非常类似:this指当前对象,super指父类对象
调用父类的属性和方法
public class Father {
public int age = 60;
public void play() {
System.out.println("下象棋");
}
}
public class Son extends Father {
public int age = 16;
@Override
public void play() {
System.out.println("玩游戏");
}
public void showAge() {
int age = 20;
System.out.println("局部变量:" + age);
System.out.println("当前对象成员变量:" + this.age);
System.out.println("父类对象成员变量:" + super.age);
}
public void callPlay() {
// 调用当前对象的方法
this.play();
// 调用父类对象的方法
super.play();
}
}
public class Demo {
public static void main(String[] args) {
Son son = new Son();
son.showAge();
son.callPlay();
}
}
调用父类的构造方法
默认调用父类的无参构造,且必须在代码的第一行
class Father {
private String name;
public Father() {
System.out.println("Father's Constrator be performed");
}
public Father(String name) {
System.out.println("Father's Constrator be performed with name");
}
}
class Son extends Father {
private int age;
public Son() {
super();
System.out.println("Son's Constrator be performed");
}
public Son(String name, int age) {
super(name);
this.age = age;
System.out.println("Son's Constrator be performed with name and age");
}
}
public class TestSon {
public static void main(String[] args) {
Son son = new Son();
}
}
【注意】super() 和this() 代码不能共存(都必须在首行),但是实际效果其实是可以的,如果不写 super() 也会自动调用
总结
1、super指父类对象,对比this关键字,使用方法都一样
2、super() 和this() 代码不能共存(都必须在首行),但是实际效果其实是可以的,如果不写 super() 也会自动调用
3、父类的属性要交给父类的构造方法去操作,没什么事就不要去使用 super() 来调用父类的构造方法了
final关键字
概述
final表示最终的,用来修饰变量,方法和类
1、final 修饰的局部变量只能被赋值一次
2、final 修饰的成员变量
3、final 修饰的基本类型变量是一个常量(只能被赋值一次),引用类型变量不可修改地址,如对象
4、final 修饰的方法不能被重写
5、final 修饰的类不能被继承
package com.fc.j._final;
/*
* final修饰的局部变量
*/
public class FinalDemo1 {
public static void main(String[] args) {
// 测试final修饰的修饰的变量
final int num;
num = 10;
System.out.println(num);
/*
* 被final修饰的变量只能赋值一次
*
* The final local variable num may already have been assigned
*
* 被final修饰的局部变量num可能已经被赋值
*/
// num = 20;
}
}
// final修饰的类不能被继承,断子绝孙
class Father {
/*
* final 修饰的成员变量必须在声明时就赋值
*
* The blank final field age may not have been initialized
* 空白的final成员变量可能未被初始化
*/
// final int age;
final int age = 16;
public final void play() {
System.out.println("下棋");
}
}
class Son extends Father {
/*
* Cannot override the final method from Father
* 无法重写被final修饰的方法
*/
// @Override
// public final void play() {
//
// }
}
特点
final修饰可以保证安全性,比如数组的长度属性,String类,这些都是final修饰的,保证不可变
总结
1、final表示最终的,可以修饰变量方法和属性
2、final修饰的基本数据类型的成员变量只能被赋值一次
3、final修饰的引用数据类型的成员变量地址不可变,但不影响对堆中元素的操作
4、final修饰的方法不能被重写
5、final修饰的类不能被继承
static关键字
概述
static 关键字方便在没有创建对象的情况下来进行调用方法和变量(优先级高于对象),可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能
static变量
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。
public class PersonDemo {
public static void main(String[] args) {
Person person1 = new Person("张三", 16);
Person person2 = new Person("李四", 17);
Person person3 = new Person("王五", 18);
Person person4 = new Person("赵六", 19);
/*
* The static field Person.address should be accessed in a static way
* 静态成员变量应该通过静态的方式访问(注意这里是应该,不是必须)
*
* Change access to static using 'Person' (declaring type)
* 使用Person声明类型来更改对静态的访问
* 通过类名来操作成员变量:Person.address
*/
System.out.println("姓名:" + person1.name + " 年龄:" + person1.age + " 地址:" + Person.address);
System.out.println("姓名:" + person2.name + " 年龄:" + person2.age + " 地址:" + Person.address);
System.out.println("姓名:" + person3.name + " 年龄:" + person3.age + " 地址:" + Person.address);
System.out.println("姓名:" + person4.name + " 年龄:" + person4.age + " 地址:" + Person.address);
// 通过类名直接调用static修饰的成员变量,此时是没有对象的
System.out.println("没有对象:" + Person.address);
/*
* Cannot make a static reference to the non-static field Person.name
*
* 将name添加static后没有报错
*/
// System.out.println("没有对象:" + Person.name);
/*
* 通过对象调用statice修饰的成员方法
*
* The static method test() from the type Person should be accessed in a static way
*/
// person1.testStatic();
// 通过类名直接调用静态方法
Person.testStatic();
}
}
总结
1、通过类名调用静态变量,因为静态变量与对象无关
2、静态变量被所有对象共享,一处更改处处更改
static方法
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
public class Person {
public String name = "张三";
public int age;
public static String address = "郑州";
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
// 自定义static修饰的成员方法
public static void testStatic() {
/*
* 静态方法不能调用非静态方法
* Cannot make a static reference to the non-static method test() from the type Person
*/
// test();
System.out.println("static mothed");
/*
* 不能再静态方法中使用this关键字
*
* Cannot use this in a static context
*/
// this.name;
}
public void test() {
System.out.println("method");
}
}
总结
1、static修饰的方法不能访问本类中的非静态变量和方法,不能使用this
2、通过类名来调用静态方法,工具类的应用很广泛
总结
1、static修饰的成员变量和方法都是对象所共享的资源,对其进行的操作会作用于所有对象。
2、static修饰的成员变量和方法依赖于类不依赖于对象,即没有对象
3、static修饰的成员变量和成员方法都可以通过类名调用,没有对象
4、静态不能调用非静态,不能使用this关键字,没有对象
5、静态成员变量常和final关键字搭配作为常量使用,静态方法常用于工具类
代码块
在 Java 中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程)
构造代码块
格式:
{
}
注意
1、用于给对象初始化,多个构造方法中相同的代码存放到一起,每次调用构造方法都会执行,并且在构造方法前执行
2、只有创建对象时调用,类不能调用
3、构造代码块可以有多个,建议只写一个
class Person {
{
System.out.println("Person构造代码块执行");
}
public Person() {
System.out.println("Person构造方法执行");
}
}
public class TestPerson {
public static void main(String[] args) {
System.out.println("main方法");
new Person();
new Person();
}
}
静态代码块
格式:
static {
}
注意
1、用于给类进行初始化,在加载的时候就执行,并且只执行一次
2、优先级高于主函数
3、静态代码块可以有多个,顺序执行,建议只写一个
class Person {
static {
System.out.println("Person静态代码块执行");
}
public Person() {
System.out.println("Person构造方法执行");
}
}
public class TestPerson {
static {
System.out.println("静态代码块1执行");
}
public static void main(String[] args) {
System.out.println("main方法");
new Person();
new Person();
}
static {
System.out.println("静态代码块2执行");
}
}
结果
静态代码块1执行
静态代码块2执行
main方法
Person静态代码块执行
Person构造方法执行
Person构造方法执行
代码块相关执行顺序
public class Father {
public Father() {
System.out.println("父类构造方法执行~~~");
}
{
System.out.println("父类构造代码块执行~~~");
}
static {
System.out.println("父类静态代码块执行~~~");
}
public static void function() {
System.out.println("父类静态成员方法执行~~~");
}
}
public class Son extends Father{
public Son() {
System.out.println("子类构造方法执行~~~");
}
{
System.out.println("子类构造代码块执行~~~");
}
static {
System.out.println("子类静态代码块执行~~~");
}
public static void function() {
System.out.println("子类静态成员方法执行~~~");
}
public static void main(String[] args) {
System.out.println("main方法执行~~~");
new Son();
}
}
结果
父类静态代码块执行~~~
子类静态代码块执行~~~
main方法执行~~~
父类构造代码块执行~~~
父类构造方法执行~~~
子类构造代码块执行~~~
子类构造方法执行~~~
面试题
执行顺序
public class Test {
static Test test1 = new Test();
static Test test2 = new Test();
static {
System.out.println("静态代码块");
}
{
System.out.println("构造代码块");
}
public Test() {
System.out.println("构造方法");
}
public static void main(String[] args) {
System.out.println("main方法");
new Test();
}
}
结果
构造代码块
构造方法
构造代码块
构造方法
静态代码块
main方法
构造代码块
构造方法
总结
1、构造代码块用于给对象初始化,每次创建对象都会调用构造代码块,并且执行顺序在构造方法之前
2、静态代码块用于给类初始化,当类被加载的时候就会调用静态代码块(只执行一次),执行顺序在main方法
abstract关键字【抽象类】
不能实例化的类就是抽象类,用 abstract 修饰
构成
abstract class 类名 {
成员变量
构造方法
成员方法
非抽象方法
抽象方法
}
要求
1、抽象类和抽象方法必须用关键字 abstract 修饰
2、抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
3、abstract 修饰的方法没有方法体,且子类必须重写
4、抽象类不能实例化,因为 abstract 类中有 abstract 方法
5、抽象类的子类
也可以是一个抽象类,可以重写也可以不重写父类的抽象方法。
可以是一个具体类。这个类必须重写抽象类中的所有抽象方法。(可以实例化)
public class TestSon {
public static void main(String[] args) {
Son son = new Son();
son.play();
}
}
// 抽象类
abstract class Father {
String name;
int age;
public Father() {
}
public void eat() {
System.out.println("吃饭");
}
// 抽象方法
abstract public void play();
}
class Son extends Father {
// 抽象方法的重写
@Override
public void play() {
System.out.println("玩游戏");
}
}