目录
一、类和对象
类的介绍
类和对象的关系
类的组成
创建对象和使用对象的格式
二、成员变量和局部变量
三、this关键字
四、构造方法
构造方法概述
构造器:
格式:
执行时机:
构造方法注意事项
五、面向对象三大特性之封装
标准JavaBean
六、static关键字
static 修饰成员的特点
应用场景
注意事项
七、面向对象三大特性之继承
继承介绍
继承的格式
什么时候使用继承?
继承中的成员访问特点 - 成员变量
继承中的成员访问特点 - 成员方法
权限修饰符
Java 中继承的特点
继承中的成员访问特点 – 构造方法
this和super
八、final关键字
九、抽象类
抽象类介绍
注意事项
十、接口
接口介绍
接口中的成员特点
类和接口之间的各种关系
抽象类和接口的对比
十一、面向对象三大特性之多态
多态的前提
多态的成员访问特点
多态的好处和弊端
十二、内部类与Lambda表达式
内部类的介绍
内部类成员访问
内部类——面试题
内部类的分类
静态内部类
局部内部类(鸡肋语法,了解即可)
匿名内部类(最重要)
Lambda表达式
就近原则
调用本类成员
this.本类成员变量 : 如果不涉及变量重复, this.可以省略
this.本类成员方法(); : 没有前提条件 this.可以直接省略
代表当前类对象的引用 (地址)
初始化一个新建的对象
构建、创造对象的时候,所调用的方法
这题的正确答案是D。考察的知识点是:
也就是说,在该 Dog 类中,存在以下两个构造方法:
使用类设计对象时
将需要处理的数据
以及处理这些数据的方法, 设计到对象中
优点:
1、这个类中的成员变量都要私有,并且要对外提供相应的getXxx ,setXxx方法
2、类中提供无参, 带参构造方法
public class Student {
private String name;
private int age;
public Student() { //无参构造
}
public Student(String name, int age) { //带参构造
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
}
多了一种调用方式, 可以通过类名调用(推荐通过类名调用) ,例如:
随着类的加载而加载, 优先于对象存在(在创建对象之前就能访问),例如:
static用于工具类的例子:
static 方法中, 只能访问静态成员 (静态只能访问静态)
static 中不允许使用 this 关键字(因为对象贝被new出来之后才会有this,而static先于对象存在)
这题答案选A,考察的知识点是静态只能访问静态,在 Java 中,静态方法(static method)是属于类的方法,可以直接通过类名调用,而非静态方法则是属于对象的方法,需要通过对象来调用。当在静态方法中引用一个字段时,该字段必须也是静态的,否则会出现"Non-static field 'arr' cannot be referenced from a static context"的报错
想要解决这两个报错,对症下药即可,下面是两种解决方法
方法一:
public class MyClass {
int arr; // 非静态字段
public static void myStaticMethod() {
MyClass obj = new MyClass(); // 创建 MyClass 的实例
obj.arr = 5; // 通过实例访问非静态字段 arr
}
}
方法二:
public class MyClass {
static int arr; // 静态字段
public static void myStaticMethod() {
arr = 5; // 直接在静态方法中访问静态字段 arr
}
}
注意事项:
Java只支持单继承,不支持多继承(一个子类只能继承一个父类),但支持多层继承(类2可继承类3,类1可继承类2,嵌套关系)
抽象类是一种特殊的父类,内部可以编写抽象方法
一个子类只可继承一个父类,但一个类可以实现多个接口
有继承 / 实现关系
有方法重写
有父类引用指向子类对象,或接口引用指向实现类对象
1. 对象多态
Animal a1 = new Dog();
Animal a2 = new Cat();
好处: 方法的形参定义为父类类型, 这个方法就可以接收到该父类的任意子类对象了
2. 行为多态
好处: 同一个方法, 具有多种不同表现形式, 或形态的能力
package com.itheima.polymorphism;
public class PolymorphismTest1 {
public static void main(String[] args) {
useAnimal(new Dog());
useAnimal(new Cat());
}
public static void useAnimal(Animal a) { // Animal a = new Dog(); =>有父类引用指向子类对象
a.eat(); // Animal a = new Cat();
}
}
abstract class Animal {
public abstract void eat();
}
//有继承 / 实现关系
class Dog extends Animal {
//有方法重写
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
1. 成员变量 : 编译看左边(父类), 运行看左边(父类)
2. 成员方法 : 编译看左边(父类), 运行看右边(子类)
package com.itheima.polymorphism;
public class PolymorphismTest2 {
public static void main(String[] args) {
Fu f = new Zi();
System.out.println(f.num);
f.show();
f.print(); // Fu.print();
System.out.println("-----------------");
Inter i = new InterImpl();
i.method();
}
}
interface Inter {
void method();
}
class InterImpl implements Inter {
@Override
public void method() {
System.out.println("method...");
}
}
class Fu {
int num = 10;
public void show() {
System.out.println("Fu...show");
}
public static void print(){
System.out.println("Fu...print");
}
}
class Zi extends Fu {
int num = 20;
@Override
public void show() {
System.out.println("Zi...show");
}
public static void print(){
System.out.println("Zi...print");
}
}
多态的好处 :提高了程序的扩展性
对象多态 : 将方法的形参定义为父类类型, 这个方法可以接收该父类的任意子类对象
行为多态 : 同一个行为, 具有多个不同表现形式或形态的能力
多态的弊端:不能使用子类的特有成员(因为编译看左边,若调用子类特有成员,编译会报错)
如果非要调用子类的特有成员,则需要用到多态转型
内部类就是定义在一个类里面的类
但如果内部类中的成员与外部类中的成员重名,那就有不同的访问方式,接下来看一道经典的面试题
成员内部类、静态内部类、局部内部类(鸡肋语法,了解即可)、匿名内部类(最重要)
new 类名(){} : 代表继承这个类
new 接口名(){} : 代表实现这个接口
当一个函数的形参是接口时,我们应该利用多态,传入其实现类对象
传入对象有两种方法:
方法一:写一个类来实现接口,再用这个实现类来创建对象(适用于接口中的抽象方法多的情况)
方法二:匿名内部类(适用于接口中的抽象方法少的情况)
代码示例(普通方法与匿名内部类方法的对比)
package com.itheima.inner;
public class AnonClassTest1 {
/*
new 类名(){} : 代表继承这个类
new 接口名(){} : 代表实现这个接口
*/
public static void main(String[] args) {
// 问题: 方法的形参是接口类型, 我们该传入的是什么?
// 答案: 传入的是该接口的实现类对象
useInter(new InterImpl()); //方法一:写一个类来实现接口,再用这个实现类来创建对象
useInter(new Inter(){ //方法二:匿名内部类
@Override
public void show() {
System.out.println("匿名内部类...show...");
}
});
}
public static void useInter(Inter i){ // Inter i = new InterImpl(); => 多态
i.show();
}
}
interface Inter {
void show();
}
class InterImpl implements Inter { //方法一:写一个类来实现接口,再用这个实现类来创建对象
@Override
public void show() {
System.out.println("InterImpl...show...");
}
}
Lambda表达式是匿名类内部类的简化语法,类似于JS中的箭头函数