静态方法只能调用静态方法,非静态方法可以调用静态方法:
public static void main(String[] args) { //静态方法 static 可以直接用类名.方法名直接调用 //非静态方法 需要先实例化这个类 new Student student = new Student(); student.say(); } public static void a(){ //b(); 此时调用b会报错 因为static是和类一起加载的 b()此时还没有加载 } //类实例化 之后才存在 public void b(){ }
普通的函数:传进去的参数是拷贝的一份
//引用传递:对象 ,本质还是值传递 public class demo03 { public static void main(String[] args) { Person person =new Person(); System.out.println(person.name); //null demo03.change(person); System.out.println(person.name); //xxx } public static void change(Person person){ person.name = "xxx"; //因为person是一个对象 指向的--->Person person - new Person() 这是一个具体的人 可以改变属性 } } class Person{ String name; }
一个类即使什么都不屑,它也会存在一个方法(构造器)
类中的构造器也称为构造方法,是在创建对象的时候必须调用的。并且构造器有以下两个特点:
1.必须和类的名字相同
2.必须先没有返回类型,也不能写void
public class Person { String name; //作用:实话初始值 //1.使用new关键字,本质是在调用构造器 //2.用来初始化值 public Person(){ //构造器 this.name = "alingo"; } //有参构造: 一旦定义了有参构造,无参就必须显式定义 public Person(String name){ this.name = name; } //alt + insert 自动生成构造器(根据属性来构造) }
public class Pet { public String name; public int age; public void shout(){ System.out.println("叫了一声"); } }
//一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { Pet dog = new Pet(); dog.name = "旺财"; dog.age = 3; dog.shout(); Pet cat = new Pet(); } }
高内聚,低耦合:高内聚:类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用
属性私有,get/set
关键词: extends 子类(派生类)是父类的扩展
Java类中只有单继承,没有多继承!(一个儿子只能有一个父亲,但一个父亲可以有多个儿子)
还有组合的关系:
public class Student { Person person; }
子类继承了父类,就会拥有父类的全部public方法、pulic属性
//在Java类中,所有的类都默认直接或间接继承了Object类 public class Person /*extends Object*/{ // 默认就是public //private //protected private int money = 10_0000_0000; public void say(){ System.out.println("说了一句话"); } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } }
super调用父类的构造方法,必须在构造方法的第一个
super必须只能出现在子类的方法或者构造方法中
super和this 不能同时调用构造方法
本升调用者这个对象
super:代表父类对象的应用
前提:
this: 没有继承也可以使用
siper:只能在继承条件才可以使用
构造方法:
需要有继承关系,子类重写父类的方法
方法名必须相同
参数列表必须相同(不然就是重载了)
修饰符:范围可以扩大:public > Protected > Default > private
抛出的异常:范围,可以被缩小,但不能被扩大:
ClassNotFoundException-->Exception(大)
为什么需要重写:
Alt + Insert: override
静态方法:
public static B{ public static void test(){ System.out.println("B"); } } public static A extends B{ public static void test(){ System.out.println("A"); } } A a = new A(); a.test();//输出 A //父类的引用指向了子类 //方法的调用只和左边,定义的数据类型有关 B b = new A(); b.test();// 输出B
非静态方法:重写
public class B { public void test(){ System.out.println("B"); } } public class A extends B{ //Override 重写 @Override //注解:有功能的注释! public void test() { System.out.println("A"); } } A a = new A(); //输出的是A a.test(); B b = new A(); //输出的仍然是A 因为子类重写了父类的方法 只在非静态方法中有效 因为非静态方法在创建时加载好了 b.test();
静态的方法和非静态的方法区别很大
静态方法:方法的调用之和左边,即定义的数据类型有关
非静态:重写
即同一方法可以根据发送对象的不同而采用不同的行为方式
一个对象的实际类型是确定的,但引用类型就不确定了
Student s1 = new Student(); //Student 能调用的方法都是自己的或者继承父类的 //Person 父类型 可以指向子类,但是不能调用子类独有的方法 //可以指向的引用类型不确定 Person s2 = new Student(); //Person 是Student的父类 这里是父类的引用指向子类 Object s3 = new Student(); //同理 //同样是Student对象,但有不同状态:多态 s1.eat(); s2.eat();
对象能执行哪些方法,主要看对象左边声明的类型,和右边关系不大!
所以子类指向的引用和父类指向的引用是不同的
子类 能调用的方法都是自己的或者继承父类的
父类型 可以指向子类,但是不能调用子类独有的方法
多态是方法的多态,属性没有多态
父类和子类,有联系 父类和子类才能进行类型转换, 否则出现类型转换异常:ClassCastException
存在条件:继承关系 方法需要重写, 父类引用指向引用指向子类对象 Father f1 = new Son();
不能重写的方法:
static 方法,属于类,它不属于实例
final 常量
private
instance of
判断两个类之间是否有父子关系
编译,判断的是左边,即数据类型如果不满足父子关系就直接报错了
而运行出来为false是判断右边的对象
Object object = new Student(); System.out.println(object instanceof Student); //true System.out.println(object instanceof Person); //true System.out.println(object instanceof Object); //true System.out.println(object instanceof String); //false Person person = new Student(); System.out.println(person instanceof Student); //true System.out.println(person instanceof Person); //true System.out.println(person instanceof Object); //true //System.out.println(person instanceof Teacher); //false //System.out.println(person instanceof String); //编译报错
类型转换
//高 低 Person student = new Student(); //低到高 不需要强制类型转换 子类到父类,可能丢失自己本来的一些方法 Student student = (Student) obj; //高到低 需要强制类型转换
总结
父类引用指向子类对象(不能反过来)
把子类转化成父类,向上转型,不需要强制类型转换
把父类转化为子类,向下转型,需要强制转换
静态变量对于类,所有对象(实例)所共享,当直接使用类去调用也说明这个变量是静态的:
public class Student { private static int age; //静态的变量 private double score; //非静态的变量 public static void go(){ } public void run(){ go(); //非静态函数可以调用静态函数 反之则不行 因为静态是先加载的 } public static void main(String[] args) { Student s1 = new Student(); System.out.println(Student.age); //System.out.println(Student.score); 会报错 因为score不是静态变量 System.out.println(s1.age); System.out.println(s1.score); Student.go(); go(); //Student.run(); 会报错 非静态方法必须new出对象后再使用 } }
public class Person { //顺序2: 一般用来赋初值 { System.out.println("匿名代码块"); //代码块 (匿名代码块) 创建对象的时候创建 且在构造器函数之前 } //只执行一次 顺序:1 static{ System.out.println("静态代码块"); //静态代码块 和类加载的时候执行,且只执行一次 } //顺序:3 public Person() { System.out.println("构造方法"); } public static void main(String[] args) { Person person = new Person(); //分别输出了 静态代码块、匿名方法块、构造方法 Person person2 = new Person(); //只输出了匿名代码块、构造方法 } }
import static java.lang.Math.random; import static java.lang.Math.PI; public class Test { public static void main(String[] args) { System.out.println(Math.random()); //没导入之前需要加Math. //通过静态导入之后就可以直接调用了 System.out.println(random()); System.out.println(PI); } }
是修饰常量的关键字,修饰之后它也不能再有子类了,不能再被继承了
用abstract关键字修饰
//abstract抽象类 :类 extends :单继承 有局限性 (接口可以多继承) public abstract class Action { //约束 让别人帮我们实现 //abstract 抽象方法 只有方法名,没有方法的实现 public abstract void doSomething(); //1. 不能new 这个抽象类,只能靠子类去实现它: 约束! //2. 抽象类中可以写普通的方法 //3. 抽象方法必须在抽象类中 //存在的意义: 抽象出来 提高开发效率 }
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有!
接口:只有规范!自己无法写方法~专业的约束! 约束和实现分离:面向接口编程~
接口就是规范,接口的本质是契约,是对对象的抽象
用interface 关键字定义
作用:
约束
定义一些方法,让不同的人实现
方法:public abstract
属性:public static final
接口不能被实例化,接口中没有构造方法
implements 可以实现多个接口
必须要重写接口的方法~
public interface TimeService { void timer(); } //interface 定于的关键字 接口都需要有实现类 public interface UserService { //属性默认的类型是 public static final int AGE = 99 常量 int AGE = 99; //接口中的所有定义其实都是 公有 抽象的 public abstract void add(String name); void delete(String name); void update(String name); void query(String name); }
public class Outer { private int id=10; public void out(){ System.out.println("这是外部类的方法"); } public class Inner{ public void in(){ System.out.println("这是内部类的方法"); } //获得外部类的私有属性~ public void getID(){ System.out.println(id); } } } public static void main(String[] args) { Outer outer = new Outer(); //通过这个外部类来实例化内部类 Outer.Inner inner = outer.new Inner(); inner.getID(); //10 }
public class Outer { private int id=10; public void out(){ System.out.println("这是外部类的方法"); } public static class Inner{ public void in(){ System.out.println("这是内部类的方法"); } //这时候就会报错了 拿不到private 因为public会先执行 除非属性也是static的 public void getID(){ System.out.println(id); } } }
public class Outer { //局部内部类 写在方法里面的类 public void method(){ class Inner{ public void in(){ } } } }