一.类的封装
为了不让其他类直接访问类的属性,需要对类进行封装,避免对象属性赋值的随意性。
1.1类的基本封装
1.1.1 通过使用四个修饰符来对类的属性和行为进行不同的访问权限
default (默认):在同一包内可见,不使用任何修饰符。
private : 在同一类内可见,但是不能修饰——外部类
public : 对所有类可见。
protected : 对同一包内的类和所有子类可见,不能修饰——外部类
1.1.2 将属性私有化后对外提供属性的访问方法,分别是赋值方法和取值方法。
赋值方法,提供 set方法。
取值方法,提供 get方法。
如果私有化属性之后,如果提供了set方法或提供了get方法则对对象进行取值或者赋值。
1.3 this关键字
this关键字的作用为解决局部变量和成员变量的问题
1.4 构造方法
构造方法的特点
构造方法没有返回值类型。也不需要写返回值。因为它是为构建对象的,对象创建完,方法就执行结束。
构造方法名称必须和类型保持一致。
构造方法没有具体的返回值。
二. 类的继承
2.1 为什么要对类进行继承
类继承的优点:
1.避免重复编写相同的代码,提高了代码的复用性。
2.创建一个子类,并在子类中添加新的属性和方法,从而扩展父类的功能,使程序更加灵活和可扩展。
3.通过继承,可以通过抽象类或接口定义一组共享的属性和方法
2.2 继承的使用
类只支持单继承,一个类只能有一个直接父类,但是可以进行多层继承
2.3 子父类中成员变量、方法的特点
在子类中访问其他成员(成员变量、成员方法)时依据就近原则进行继承
super关键字
如果子类中出现了父类中同名的成员变量,这时子类中若要访问父类中的成员变量,必须使用关键字super来完成
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
在子类重写父类的方法时,需要注意
1.子类方法覆盖父类方法时,必须保证权限大于等于父类权限
2.子类和父类方法声明时必须一样
三.抽象类与接口
3.1 抽象类
3.1.1抽象方法、抽象类的定义格式
public abstract 返回值类型 方法名(参数);
abstract class 类名 { 语句 }
public abstract class A{
public abstract void test();
}
3.1.2 抽象类的特点
1.抽象类和抽象方法都需要abstract修饰。
2.抽象类不可以直接创建对象。
3.只有覆盖了抽象类中所有抽象方法后,其子类才可以创建对象。
4.抽象类中可以不定义抽象方法。
3.2 接口
3.2.1 接口的格式
public interface 接口名{抽象方法3、抽象方法2、抽象方法3、
}
3.2.2 接口的多继承
在Java中,类的多继承是不合法,但接口允许多继承。
在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。
public interface A extends B, C
3.3 接口和抽象类的异同
相同之处:
都可以用来实现多态性:通过接口或抽象类的引用,可以引用其实现类的对象,并调用相应的方法。
不同之处:
- 实现方式:抽象类使用继承来实现,一个类只能继承一个抽象类,而接口使用实现来实现,一个类可以实现多个接口。
- 方法体:抽象类可以包含具体的方法实现,而接口只能包含方法的签名,没有方法体。
- 构造函数:抽象类可以有构造函数,而接口不能有构造函数。
- 成员变量:抽象类可以有实例变量和静态变量,而接口只能有常量(
public static final
)。
四.类的多态
4.1 多态使用格式与实例:
父类类型 变量名 = new 子类类型();
变量名.方法名();
public class Demo {
public static void main(String[] args) {
Animal a = new Cat();
a.eat();
}
}
class Animal {
public void eat() {
System.out.println("吃东西");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
}
4.2 多态中向上转型与向下转型
多态的转型分为向上转型与向下转型两种:
向上转型:当有子类对象赋值给一个父类引用时,便是向上转型.
使用格式:
父类类型 变量名 = new 子类类型();
如:Person p = new Student();
向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用转为子类引用,这个过程是向下转型。
使用格式:
子类类型 变量名 = (子类类型) 父类类型的变量;
如:Student st = (Student) l;
五.类的高级特性
5.1 static修饰符
它用于修饰类的成员,如成员变量和成员方法等。被static修饰的成员属于类,不属于这个类的某个对象,因此在访问static修饰的成员时,就可以直接采用类名.成员的方法访问。这些成员变量和成员方法,被称之为静态成员和静态方法
public class A {
private static int B = 0;
protected static int getCount() {
return B;
}
private static void addInstance() {
B++;
}
A() {
A.addInstance();
}
public static void main(String[] arguments) {
System.out.println("Starting with " +
A.getCount() + " instances");
for (int i = 0; i < 500; ++i){
new InstanceCounter();
}
System.out.println("Created " +
A.getCount() + " instances");
}
}
5.2Final修饰符
Final修饰类不可以被继承,但是可以继承其他类
public final class Test {
// 类
}
5.3 代码块
5.3.1 局部代码块
局部代码块是定义在方法或语句中,以”{}”划定的代码区域,此时只需要关注作用域的不同即可,方法和类都是以代码块的方式划定边界的。
5.3.2 构造代码块
构造代码块是定义在类中成员位置的代码块,优先于构造方法执行,构造代码块用于执行所有对象均需要的初始化动作,每创建一个对象均会执行一次构造代码块。
class Person {
private String name;
private int age;
//构造代码块
{
System.out.println("构造代码块执行了");
}
Person(){
System.out.println("Person无参数的构造函数执行");
}
Person(int age){
this.age = age;
System.out.println("Person(age)参数的构造函数执行");
}
}
5.3.3 静态代码块
静态代码块是定义在成员位置,使用static修饰的代码块。它优先于主方法执行、优先于构造代码块执行,当以任意形式第一次使用到该类时执行。该类不管创建多少对象,静态代码块只执行一次。可用于给静态变量赋值,用来给类进行初始化。
class Person {
private String name;
private int age;
//构造代码块
Static{
System.out.println("静态代码块执行了");
}
Person(){
System.out.println("Person无参数的构造函数执行");
}
Person(int age){
this.age = age;
System.out.println("Person(age)参数的构造函数执行");
}
}
5.4 匿名对象
创建匿名对象直接使用,没有变量名,只能使用一次。
new Person().eat() eat方法被一个没有名字的Person对象调用了。
5.5 内部类
5.5.1 成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部
class C {
double radius = 0;
public C(double r) {
this.r = r;
}
class D { //内部类
public void drawSahpe() {
System.out.println("iii");
}
}
}
5.5.2 方法内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
class People{
public People() {
}
}
class Man{
public Man(){
}
public People getWoman(){
class Woman extends People{ //局部内部类
int age =0;
}
return new Woman();
}
}