static:静态的,可以更长久的存值,被static修饰的内存生命周期与程序保持一致
static可以修饰成员
静态成员
静态成员变量
静态成员方法
非静态成员
非静态成员变量
非静态成员方法
比较静态方法和非静态方法的使用?
可以多使用静态方法,有一种情况例外:当方法中要使用非静态成员时,就必须使用非静态方法。
静态方法的优点:不需要创建实例对象,节省内存,直接调用成员,比非静态的调用寻址时间少,效率高。
缺点:静态的成员会一直占用方法区的内存。
使用场景:
工具类–Arrays
单例设计模式
package com.qf.note;
public class note02 {
public static void main(String[] args) {
Person person = new Person();
person.age = 20;//通过引用给成员变量赋值
person.height = 170;//通过引用给静态成员变量赋值
//Person.height = 170;//通过类名直接给静态成员变量赋值
//Person.age = 20;//不能通过类名给非静态成员变量赋值
}
//静态内部类--也是外部内的成员
static class Person {
int age;//非静态成员变量
static int height;//静态成员变量
/*
静态方法中不能使用非静态成员
静态方法可以使用静态成员
*/
public static void jump() {//静态成员方法
System.out.println("跳");
//System.out.println(age);//静态方法中不能使用非静态成员
System.out.println(height);//静态方法可以使用静态成员
}
/*
非静态方法中既可以使用非静态成员,也可以使用静态成员
*/
public void play(){
System.out.println(age);
System.out.println(height);
}
}
}
多态:一种事物的多种形态 狗—动物—生物
在Java中的表述:父类的引用指向子类的对象。
注意:多态的前提—有继承关系
package com.qf.note;
public class note03 {
public static void main(String[] args) {
//继承
Dog dog =new Dog();
//多态--Animal的引用指向Dog的对象
//优点:可以提高代码的扩展性,使用之前定义好的功能,后面直接拿来使用,不能再创建新的方法。
//缺点:不能直接用子类调用特有的成员,但是我们可以通过向下转型达到调用子类特有方法的目的
Animal animal = new Dog();
animal.show();//animal中自己的方法
/*
- java程序运行分成两个阶段:编译、运行
编译阶段:从打开程序到执行运行之前---只能识别=前面的引用类型,不会识别=后面的对象
运行阶段:从运行开始---识别=后面对象,对象开始干活儿
*/
//animal.play();//子类特有的成员
//animal.height();//子类特有的成员
//强制将高等级的Animal类转成了低等级的Dog类---向下转型,目的:就是要在多态下实现调用子类特有方法的目的
Dog dog1 = (Dog)animal;
dog1.play();
}
static class Animal{
int age;
String name;
public void show(){
System.out.println("fu-show");
}
}
static class Dog extends Animal{
int height;
public void play(){
System.out.println("zi--play");
}
@Override
public void show() {
super.show();
}
}
}
多态—对象的转型
必须保证类与类之间是有继承关系的
向上转型:低等级的类型转成高等级
向下转型:高等级的类型转成低等级
package com.qf.note;
public class note04 {
public static void main(String[] args) {
/*
向上转型
多态本身就是向上转型
目的:完成多态
*/
Fu fu = new Zi();
/*
向下转型
将Fu类引用转成子类
目的:调用子类特有的成员
*/
Zi zi = (Zi)fu;
//注意:
Fu fu1 = new Fu();
//这里不是向下转型,向下转型的前提一定是多态
Zi zi1 = (Zi)fu1;
}
static class Fu{}
static class Zi extends Fu{}
}
package com.qf.note;
public class note05 {
public static void main(String[] args) {
Person person = new Person();
Person teacher= new Teacher();
teacher.show();
//报异常:ClassCastException
//Student student = (Student)teacher;
//使用instanceof
/*
是一个运算符
语法:对象 instanceof 当前类
解释:判断对象是否是当前类的对象或者是当前类的子类的对象,成立返回true,不成立返回false
我们将当前的操作称为容错处理
*/
if(!(teacher instanceof Student)){
//报异常
//throw抛出异常
//throw new ClassCastException("当前的对象不是Student类的对象");
}else{
Student student = (Student)teacher;
}
//举例
//多态
Person student1 = new Student();
//student1 = new Teacher();
if(!(student1 instanceof Student)){
throw new ClassCastException("当前的对象不是Student类的对象");
}else{
Student student = (Student) student1;
student.run();
}
//注意点:
//instanceof前面的对象与后面的类之间一定要在一个继承体系类
Dog dog = new Dog();
//正确,前方的是Person类的对象
if(person instanceof Person){
}
//正确,前面是Person类的子类对象
if(teacher instanceof Person){
}
//错误:前面的对象与后面没有关系
//if(dog instanceof Person){}
}
static class Person{
String name;
public void show(){
System.out.println("show");
}
}
static class Student extends Person{
int age;
public void run(){
System.out.println("run");
}
}
static class Teacher extends Person{
int weight;
@Override
public void show() {
System.out.println("Teacher-show");
}
}
static class Dog{}
}
继承
- 继承下的调用规则
- 成员变量:调用子类的
- 成员方法:调用子类的,子类没有再去调用父类的.
- 多态下的调用规则:
- 成员变量:编译的时候能不能访问看父类,运行的时候也看父类
- 成员方法:编译的时候能不能访问看父类,运行的时候看子类
- 静态成员方法:编译运行都看父类
package com.qf.note;
public class note06 {
public static void main(String[] args) {
//继承
Zi zi = new Zi();
zi.show();//调用的子类的
System.out.println(zi.age);
//多态
Fu fu = new Zi();
fu.show();//调用的父类的
System.out.println(fu.age);//调用的是父类的
}
static class Fu{
int age = 30;
public void run(){
System.out.println("Fu-run");
}
public static void show(){
System.out.println("Fu-show");
}
}
static class Zi extends Fu{
int age = 5;
public void eat(){
System.out.println("Zi-eat");
}
public static void show(){
System.out.println("Zi-show");
}
}
}
抽象类:在继承中,提取父类方法的时候,每个子类都有自己具体的方法实现,父类不能决定他们各自的实现方法,所以父类干脆就不管了,
在父类中只写方法的声明(负责制定一个规则),将方法的实现交给子类.在类中只有方法声明的方法叫抽象方法,拥有抽象方法的类叫抽象类
作用:简化代码
总结特点:
1.必须由abstact关键字修饰
2.抽象类可以没有抽象方法,但是有抽象方法的一定是抽象类
3.抽象类不能直接创建对象,我们只能通过抽象类的子类创建对象
4.抽象类的子类也可以不重写抽象类的方法,可以将自己也变成抽象的.
5.抽象类可以拥有普通类的所有成员,多拥有一种抽象方法
6.抽象方法只有方法的声明,没有实现.
package com.qf.note;
public class note07 {
public static void main(String[] args) {
//实例:计算圆形和矩形的面积
Circle circle = new Circle(2);
circle.getArea();
}
//拥有抽象方法的一定是抽象类
static abstract class Shape{
//要定制的一个规则
//没有实现的方法就是抽象方法--abstract
public abstract double getArea();
}
//抽象类的子类也可以不重写抽象类的方法,可以将自己也变成抽象的.
abstract class Test extends Shape{
}
static class Circle extends Shape{
private double r;
//final:是最终的意思,一旦被final修饰,这个变量的值就不能再被改变,变成了常量.
//们将这种称为符号常量
private final double PI = 3.14;
public Circle(double r) {
this.r = r;
}
@Override
public double getArea() {
return PI*r*r;
}
}
static class Rang extends Shape{
private double width;
private double length;
public Rang(double width,double length){
this.width = width;
this.length = length;
}
@Override
public double getArea() {
return width*length;
}
}
}
final的使用:最终的意思
可以修饰的内容
成员变量:变量就会变成常量,值不能再被更改
局部变量:变量就会变成常量,值不能再被更改
方法:不能被重写
类:不能有子类
扩展:空白final
package com.qf.note;
public class note08 {
static final int age = 4;
public static void main(String[] args) {
//用第一种
Bird bird1 = new Bird("乌鸦");
System.out.println(bird1.age);//10
System.out.println(bird1.name);
//第二种:空白final
Bird bird = new Bird("大雁");
System.out.println(bird.name);
System.out.println(bird.age);//10
}
//加final的类不能有子类
class Animal{
//final修饰的方法不能重写
public final void show(){
}
}
class Dog extends Animal{
}
//空白final演示
static class Bird{
//第一种办法:直接赋值
final int age = 10;
//第二种方法:空白final,允许用户对成员变量的赋值时间延长到构造方法结束
final String name;
public Bird(String name){
this.name = name;
}
}
}
Object:java系统的根类/基类/超类
内部包含11个基本方法
常用的
equals:判断两个对象是否相等
hashcode:获取对象的hash码值
getClass:获取对象的字节码文件对象
toString:默认打印的是包名+类名+@+hash码值,我们经常重写,用于快速打印对象属性
package com.qf.note;
public class note09 {
public static void main(String[] args) {
//equals:判断两个对象是否相等
//要求:比较两辆车大小
Car car1 = new Car(3);
Car car2 = new Car(3);
//默认比较的是对象的地址
// boolean b1 = car1.equals(car2);
// System.out.println(b1);//false
//通常我们会根据用户的需求设定条件比较对象
//比如:按照轮子个数比较--重写equals实现
boolean b1 = car1.equals(car2);
System.out.println(b1);//false
//hashcode:获取对象的hash码值
System.out.println(car1.hashCode());//460141958
System.out.println(Integer.toHexString(car1.hashCode()));//1b6d3586 十六进制的数
System.out.println(car2.hashCode());//1163157884
//getClass:获取对象的字节码文件对象
Class cl1 = car1.getClass();
Class cl2 = car2.getClass();
System.out.println(cl1.getName());//com.qf.test.Demo11$Car
System.out.println(cl1 == cl2);//true
//toString:默认打印的是包名+类名+@+hash码值,我们经常重写,用于快速打印对象属性
// System.out.println(car1.toString());//com.qf.test.Demo11$Car@1b6d3586
System.out.println(car1);//默认调用toString Car{wheelNumber=3}
}
static class Car{
int wheelNumber;
public Car(int wheelNumber){
this.wheelNumber = wheelNumber;
}
//重写equals方法--按照轮子个数
@Override
public boolean equals(Object o) {//o = new Car() 多态
//容错处理
if (!(o instanceof Car)){
throw new ClassCastException("不是Car类的对象");
}else {
//向下转型
Car car = (Car)o;
return this.wheelNumber == car.wheelNumber;
}
}
@Override
public String toString() {
return "Car{" +
"wheelNumber=" + wheelNumber +
'}';
}
}
}
接口:特殊的类,称为规则列表
语法
interface 接口名字{
成员变量:常量(默认都是public,static,final修饰的)
成员方法:抽象方法(默认都是public,abstact修饰的)
}
接口与类的关系跟类与类的关系一样
接口与类之间 子类 implements 父接口1,父接口2
类与类之间 子类 extends 父类
接口与接口之间 子接口 extends 父接口1,父接口2
总结:
1.一个类只能继承一个父类,但是可以同时实现多个接口
2.一个接口可以同时继承多个接口
3.接口本身就是抽象的,默认用关键字abstract修饰
扩展:
1.作用:接口是为了让java可以间接实现多继承
在实际的任务分配中:父类完成的主要任务,接口是辅助父类的.
2.版本
在jdk1.8之前,接口中只能有抽象的方法,
从jdk1.8开始,也可以有存在方法实现的方法,但是必须使用default或者static修饰
3.一个类可以实现多个接口,如果多个接口中出现了相同的方法?
不会,接口中的方法都是抽象的,要通过子类写具体的实现.我们在调用方法时,最终看的功能,而功能只有子类中的一份.
如果是default或者static的方法呢?
不管子类实现的多个接口中,出现了几个带实现的同名方法,作为子类,我们都必须重写这个方法.
package com.qf.note;
interface Inter1{
void play();
//从jdk1.8开始,也可以有存在方法实现的方法,但是必须使用default或者static修饰
default void show(){
System.out.println("show");
}
static void song(){
System.out.println("song");
}
}
interface Inter2{
void eat();
void play();
}
interface Inter3 extends Inter1,Inter2{
}
//子类实现了父接口后的处理
//第一种:重写父接口的方法
class Pig implements Inter1{
@Override
public void play() {
}
}
//第二种:将自己变成抽象的
abstract class Pig1 implements Inter1{
}
//继承自Object类,同时实现了两个接口
class Pig2 extends Object implements Inter1,Inter2{
@Override
public void play() {
}
@Override
public void eat() {
}
}
//实现接口Inter3
class Pig3 implements Inter3{
@Override
public void play() {
}
@Override
public void eat() {
}
}
public class note10 {
}