static——静态
static修饰的成员变量和方法,从属于类。
普通变量和方法从属于对象
静态对象不能调用非静态成员——编译报错
Java包机制package
通常是类的第一个语句
包相当于文件夹,可以实现类的管理,可以解决大量重名类的处理
包名:域名倒着写(com.jd),再加上项目名、模块名…便于内部管理
写项目时一定要加包,不要使用默认包
import静态导入(按Ctrl可查看源码
导入包的时候,如果遇到重名包 可用类似于java.util.Date 这种方法来明确指出包中类的位置,更加直观明确。
但这不是一个大量出现的情况。
比如我现在要使用一个Math属性里的PI,可以直接输出Math.PI ,但是为了更加方便,我发现Math这个属性是static静态属性方法,那么可以直接导入import static java.lang.Math.PI; /import static java.lang.Math.*; 来导入Math类的PI属性/全部属性,这时世界输出PI就行。
继承extends
类中没有多继承,接口有多继承
子承父类全部非私有属性和方法(除了构造方法)
super
直接父类对象的引用,通过super来访问父类中被子类覆盖的方法或属性
构造方法调用顺序
构造方法第一句总是:super(),不写默认补上
内存里面是一个包裹的结构
封装
高内聚低耦合 : 外部调用方便,内部复杂(类似黑箱
比如说一个电视,里面有很多电线,如果谁都能碰这些电线的话,非常的危险且不稳定,现在我用一个铁盒子把这些电线封装起来,不让人碰,这样既保证了电线的安全,也保证了用户操作的安全和简单性。
修饰符 | 同类 | 同包 | 子类 | 所有类 |
---|---|---|---|---|
private | * | |||
default | * | * | ||
protected | * | * | * | |
public | * | * | * | * |
使用细节
一般使用private 使用setter和getter获取和设定
玄机就在这里面啦,如果你想对被设置的属性进行限定(比如年龄必须>0),那么就可以把这个限定条件放到这个属性对应的setter里面
注意:对于布尔值的getter,不是getXx(),而是 isXx()
开发时通常使用自动生成,方便
一般情况的方法都是public ,因为项目一般都是公司内部使用不用考虑太多
多态
要点
多态是方法的多态,不是属性的多态
条件:继承,重写,父类引用子类对象
运行结果:shout wang!
向上转型
父类引用指向子类对象
当调用父类同名方法时,实际是执行子类重写父类的方法
有了对象多态性以后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用
向下转型(用的少
调用子类特有的方法和属性,强制转换
强制转换有风险,可能转换不成功,出现ClassCastException异常
如果想避免此错误,使用instanceof来判断。
instanceof
返回布尔值
判断某对象是否属于某类型
为了避免在向下转型时出现异常,在向下转型之前先进行instanceof判断,如果true则进行向下转型,否则不进行
package cn.sxt.dyq;
public class TestExtend {
public static void main(String[] args) {
Student stu = new Student();
System.out.println(stu instanceof Person);
}
}
class Person {
String name;
int height;
public void rest() {
System.out.println("rest");
}
}
class Student extends Person {
String major;
public void study() {
System.out.println("study 2 hours");
}
}
运行结果:true
内存分析
栈
- 描述的是方法执行的内存模型,每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口…)
- JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量…)
- 栈属于线程私有,不能实现线程共享
- 栈的存储特性:先进后出,后进先出
- 栈是由系统自动分配,速度快,是一个连续的内存空间
堆(方法区
JVM只有一个方法区,被所有线程共享
方法区实际也是堆,只适用于存储类、常量相关的信息
用来存放程序中永远是不变或唯一的内容(类信息【class对象】、静态变量、字符串常量…)
abstract抽象
抽象方法
使用abstract修饰的方法,没有方法体,只有声明。
定义是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现
抽象类
包含抽象方法的类。通过abstract方法定义规范,要求子类必须定义具体实现。
通过抽象类,可以做到严格限制子类的设计,使子类之间更加通用。
要点
- 有抽象方法的类只能定义成抽象类
- 抽象类不能用new来实例化
- 抽象类只能被子类调用
- 只能用来被继承
- 必须被子类实现
interface接口
比 抽象类 还 抽象 的 抽象类
接口里面所有方法都是默认抽象的。
只定义规范声明
im
访问修饰符:public / 默认
extends:接口可以多继承
常量:默认 public static final 修饰
方法:默认 public abstract实现接口implement
可实现多个接口
接口可以多继承(但 类 没有多继承
面向接口编程是面向对象编程的一部分
需求多变是工作中经常会遇到的问题,这个时候就要以不变应万变,接口的不变特性就体现出来了
所以接口定义好就不动了,通常动的就是实现类。内部类
成员内部类
类似一个成员放到一个类内部里面,叫成员内部类
可以使用private、default、protected、public任意进行修饰,会和外部类分别生成不同的.class文件
为外部类提供服务
有static就是静态内部类,不加就是非静态内部类非静态内部类
非静态内部类必须寄存在一个外部类对象里,所以new内部类对象之前必须先new外部类对象
Outer.Inner inner =** new Outer().new Inner();**
非静态内部类可以直接访问外部类成员,但是外部类不能直接访问非静态内部类成员(良好的封装环境
非静态内部类不能有静态方法、静态属性
外部类的静态方法,静态代码块不能访问非静态内部类静态内部类
用static修饰的内部类
不依托于外部类,所以实例化的时候不用new外部类
匿名内部类
适合只使用一次的类
输出:TestAnonymousInnerClass.main(…).new AA() {…}.aa()arraycopy数组的拷贝
void java.lang.System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
删除某元素
处理最后一个元素s1[s1.length - 1] = null;
**