位置:
成员变量在类中方法外;局部变量在方法声明中或方法内;
内存位置:
成员变量在堆内存中;局部变量在栈内存;
生命周期:
成员变量随着类的加载而加载,随着类消失而消失;
局部变量随着方法体的调用而加载,方法体调用完毕而消失;
初始化值:
成员变量有默认初始化值;
局部变量没有;
private修饰符可以修饰成员变量和方法,被修饰的成员只能在本类被访问
面对象的三大特征之一:封装
this关键字在成员变量和局部变量同名时,用this.变量名 特指成员变量;
this所在函数所属对象的引用。即,哪个对象调用了this所在的函数,this就代表哪个对象
构造方法格式:
方法名和类名相同;
没有void也没有返回值;
创造对象的时候调用,每创建一个对象,就会执行一次构造方法;
不能手动调用构造方法;
系统会默认给出无参构造方法,手动写后,系统就不会提供默认构造方法;
static 静态的意思,可以修饰成员方法,成员变量;
被static修饰的特点:
被类的所有对象共享;
随着类的加载而加载,优先于对象存在;
可以通过类名调用,也可以通过对象名调用;
注意事项:
静态方法只能访问静态的成员;
非静态方法可以访问静态的成员,也可以访问非静态的成员
静态方法中是没有this关键字
子类继承父类,子类可以有父类的成员;
子类还可以重新定义方法,以及添加新的成员;
面对象的三大特征之一:继承
继承的好处:
提高代码的复用性;
提高代码的维护性;
继承的坏处:
使得类的耦合性增强,削弱子类的独立性
java中只能单继承,不能多继承,但可以多层继承
super关键字父类存储空间的标识
super和this的区别
成员变量:
this.成员变量 访问本类成员变量
super.成员变量 访问父类成员变量
成员方法:
this.成员方法 访问本类成员方法
super.成员方法 访问父类成员方法
构造方法:
this(…) 访问本类构造方法
super(…) 访问父类构造方法
子类中所有的构造方法默认都会访问父类中无参的构造方法
方法重写子类中的方法和父类中的方法声明一样,包括方法名,参数列表;
注意事项
父类中的私有方法不能被重写;
子类重写的方法访问权限不能比父类低;(public→protected→default→private)
静态方法不能被重写;
用abstract修饰的类是抽象类;
注意事项
抽象类中不一定有抽象方法,有抽象方法的一定是抽象类;
抽象类不能实例化;
抽象类的子类要么也是抽象类,要么重写父类的所有抽象方法;
public abstract class Animal {
public void drink(){
System.out.println("喝水");
}
public Animal(){
}
public abstract void eat();
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
fianl关键字
表示最终的意思,可以修饰成员方法,成员变量和类
特征:
被final修饰的类不能被继承,但可以有父类;
被final修饰的方法不能被重写;
被final修饰的成员变量,不能被再次赋值;
1,如果成员变量是 基本数据类型,则不能改变值;
2,如果成员变量是 引用数据类型,则不能改变地址值;
使用{}括起来的代码被称为代码块;
局部代码块:
位置:方法内
作用:限定变量的生命周期,及早释放,提高内存利用率;
构造代码块:
位置:类中方法外
特点:每次构造方法执行时,都会执行构造代码块的代码,并在在构造方法执行前执行;
作用:多个构造方法中相同的代码提取出来,提高代码复用性
静态代码块:
位置:类中方法外
特点:被static修饰,随着类加载而加载,并且只执行一次;
作用:在类加载的时候做数据初始化;
接口不能实例化,但我们可以创建接口的实现类对象使用
接口的子类
要么重写接口中的所有抽象方法
要么子类也是抽象类
//用interface修饰
public interface 接口名 {}
//实现接口用implements
public class 类名 implements 接口名{}
接口的特点
成员变量:只能是常量,默认修饰符 public static final
构造方法: 接口没有构造方法
成员方法:只能是抽象方法,默认修饰符 public abstract
类和接口之间的关系
类与类:单继承或者多层继承
类与接口:单继承、单实现、多实现
接口与接口:单继承、多继承
接口的java8更新:
java8:默认方法:
public default 返回值类型 方法名(参数列表) { }
注意事项:默认方法不是抽象方法,所以不强制被重写。但是可以被重写,重写的时候去掉default关键字
java8:静态方法:
public static void 方法名() {}
注意事项:静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
接口的java9更新:
java9:私有方法:
//格式一:
private void 方法名() {}
//格式二:
private static void 方法名(){}
注意事项:
默认方法可以调用私有的静态方法和非静态方法
静态方法只能调用私有的静态方法
多态前提:
要有继承关系;
要有方法重写;
要有父类引用指向子类对象
class Animal {
public void eat(){
System.out.println("动物吃饭");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Test{
public static void main(String[] args) {
//父类引用指向子类对象
Animal a = new Cat();
a.eat();
}
多态的访问特点
成员变量:编译看左边(父类),运行看左边(父类)
成员方法:编译看左边(父类),运行看右边(子类)
多态转型
向上转型:父类引用指向子类对象
向下转型:父类引用的子类对象,子类对象转换回子类
class Fu{
public void aaa(){
System.out.println("我是父类");
}
}
class Zi extends Fu{
public void aaa(){
System.out.println("我是子类,重写了aaa方法");
}
public void bbb(){
System.out.println("我是子类新加方法");
}
}
public class Test{
public static void main(String[] args){
Fu f =new Zi();//多态向上转型
f.aaa();//成员方法运行看右边
//f.bbb();//编译会报错
Zi z=(Zi)f;//向下转型
z.bbb();
}
}
注意事项:
向下转型时,可能会出现目标类型和实际类型不符合。
所以向下转型时,可以用instanceof关键字判断
if(f instanceof Zi){
Zi z =(Zi)f;
}
内部类
在类中定义一个类
class Out{
public class In{
}
}
//==========================================
public class Outer {
private int num = 10;
public class Inner {
public void show() {
System.out.println(num);
}
}
public void method() {
Inner i = new Inner();
i.show();
}
}
成员内部类
位置:类中方法外
访问内部类格式:
外部类名.内部类名 对象名=new 外部类名().new 内部类名();
Out.In oi = new Out().new In();
静态成员内部类
访问格式:
外部类名.内部类名 对象名=new 外部类名().内部类名();
静态方法访问格式:
外部类名.内部类名.方法名();
class Out{
static class In{
public void aaa(){
System.out.println("内部类方法");
}
public static void bbb(){
System.out.println("内部类静态方法");
}
}
}
public class Test{
public static void main(String[] args){
//创建内部静态类对象
Out.In oi = new Out.In();
oi.aaa();
//访问内部类静态方法
Out.In.bbb();
}
}
局部内部类
位置:类中方法中
注意事项:
局部内部类可以直接访问外部类的成员,也可以访问方法内的局部变量
局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
class Out{
private int a = 1;
public void method(){
int b = 2;
//局部内部类
class In{
public void show(){
//访问外部类成员
System.out.println(a);
//访问方法内局部成员
System.out.println(b);
}
}
//外界无法访问局部内部类,所以要在方法内提供方法
In i =new In();
i.show();
}
}
public class Test{
public static void main(String[] args){
Out o=new Out();
o.method();
}
}
匿名内部类
前提:存在一个类(抽象类也行)或者接口;
格式:
new 类名(){ 重写方法 }
new 接口名(){ 重写方法 }
本质:是一个继承了该类或者实现了该接口的子类匿名对象
new In(){
@Override
public void aaa(){
System.out.println("我被重写了");
}
}
匿名内部类直接调用方法
interface Inter{
void method();
}
class Test{
public static void main(String[] args){
new Inter(){
@Override
public void method(){
System.out.println("我是匿名内部类");
}
}.method(); // 直接调用方法
}
}
Lambda表达式
前提:有一个接口,并且接口只有一个抽象方法
//无参无返回值
//接口
public interface Cat{
void eat();
}
//实现类
public class CatImpl implements Cat{
@Override
public void eat(){
System.out.println("猫吃鱼");
}
}
//测试类
public class Test{
public static void main(String[] args){
//普通方法调用
Cat c =new CatImpl();
c.eat();
//匿名内部类
new Cat(){
@Override
public void eat(){
System.out.println("猫吃鱼");
}
}.eat();
//Lambda表达式
Cat c =()->{System.out.println("猫吃鱼")};
}
}
//===================================================
//有参有回值
//接口
public interface Cat{
int eat(int a);
}
//实现类
public class CatImpl implements Cat{
@Override
public int eat(int a){
System.out.println("猫吃鱼");
return a++;
}
}
//测试类
public class Test{
public static void main(String[] args){
//普通方法调用
Cat c =new CatImpl();
int a = c.eat(1);
//匿名内部类
int b = new Cat(){
@Override
public int eat(int a){
System.out.println("猫吃鱼");
return a++;
}
}.eat(2);
//Lambda表达式
Cat cc =(int a)->{System.out.println("猫吃鱼");return a++;};
int d=cc.eat(3);
}
}
Lambda表达式省略模式
参数类型可以省略。但是有多个参数的情况下,不能只省略一个
(int a,int b)->{System.out.println(a+b)};
省略后: (a,b)->{System.out.println(a+b)};
如果参数有且仅有一个,那么小括号可以省略
(int a)->{System.out.println(a)};
省略后: a->{System.out.println(a)};
如果代码块的语句只有一条,可以省略大括号和分号,和return关键字
(int a,int b)->{return a+b;};
省略后: (a,b)->a+b;



