- 同一个包下的类不需要导入就可以使用,不同包下的类,必须导入包才能使用。
- static修饰静态方法,静态方法可以通过类名.方法名,进行调用,非静态方法通过这种方式进行调用会报错。
- static修饰的内容是和类一起加载的,非静态方法是和对象一起生成的(类实例化之后才存在),所以static方法不能调用非静态方法。
- Java是值传递
- 一个类里只能有一个public的类
package oop;
public class Student {
//静态方法 通过类名.方法名 调用
public static void say(){
System.out.println("学生说话了");
}
//非静态方法
public void speak(){
System.out.println("学生讲话了");
}
}
值传递
package oop;
//java是值传递
public class Demo04 {
public static void main(String[] args) {
int a=1;
System.out.println(a);
test(a);
System.out.println(a);
}
public static void test(int a){
a=10;
}
}
引用传递
package oop;
public class Demo05 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);
person.name="123";
System.out.println(person.name);
change(person);
System.out.println(person.name);
}
public static void change(Person person){
person.name="000";
}
}
class Person{
String name;
}
- 一个项目应该只存在一个main方法
无参构造 有参构造
当没有定义构造器的时候,会自动生成一个无参构造器,
当自定有构造器之后,就不会生成无参构造器,必须显示定义无参构造器
一个类即使什么都不写,也会存在一个方法,即无参构造器
构造器特点及作用
- 实例化初始值,初始化对象的值
- 使用new关键字,本质是在调用构造器
- alt+insert会自动生成构造器
- 和类名相同,没有返回值
创建对象内存分析
面向对象三大特性:封装、继承、多态
封装
使用private关键字,属性私有,通过get、set方法获取和更改变量内容。
当有多个属性的时候,可以使用alt+insert快捷键组合批量生成get、set方法
【封装的意义】:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统的可维护性增加了
重载
方法名相同,参数列表不同
继承
*** 经过final修饰的类就不能被继承了,即:没有子类了
子类继承了父类,就会拥有父类的全部方法,私有的除外,私有的可以被被继承,但是不能直接访问到。
将光标放在类内,配合ctrl+H会在右侧打开继承树。
在Java中,所有的类都默认直接或者间接继承Object类
Java中只有单继承,没有多继承。
super
- super调用父类的构造方法,必须在构造方法的第一个
- super只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
super VS this
- 代表的对象不同:this代表本身调用者这个对象 super代表父类对象
- this没有继承也可以使用,super只有在继承的条件下才能使用
环境准备
【Person.java】
package oop.demo05;
//Person 是 人
public class Person {
public Person() {
System.out.println("Person无参构造器被执行了");
}
private int money= 1000;
protected String name = "小明";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(int money) {
this.money = money;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public void say(){
System.out.println("说了一句话");
}
}
【Student.java】
package oop.demo05;
//Student 是 人
public class Student extends Person{
private String name="xiaoming";
public Student() {
System.out.println("Student的无参构造执行了");
}
public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
【Application.java】
package oop;
import oop.demo05.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("test");
}
}
Person是父类 Student继承Person类,是Person的子类,Application是测试类
【输出】
Person无参构造器被执行了
Student的无参构造执行了
test
xiaoming
小明
Student student = new Student();的时候会先调用父类的无参构造,再调用子类的无参构造。
子类构造器不写super默认调用无参构造,写super可以指定调用有参/无参构造
方法重写
重写都是方法重写和属性无关
只能对public非静态的方法进行重写
静态方法:方法的调用只和左边的数据类型
非静态方法:重写
注意点:
- 方法名相同,参数列表相同
- 修饰符:范围可以扩大,不能缩小 public>protected>default>private
- 抛出的异常:范围:可以缩小,不能扩大 ClassNotFoundException —>Exception(大)
为什么需要重写?
- 父类的方法,子类不一定需要,或者不一定能满足子类的需求
Alt+insert override
多态
一个对象的实际类型的确定的,引用类型是不一定的,父类引用指向子类。
一个对象能执行哪些方法,主要看左边类型,和右侧的关系不大。
run()子类没有重写的时候,s1和s2会调用父类的run方法,run()子类重写的时候,s1和s2会调用子类的run方法
Object o=new Student();
System.out.println(o instanceof Object);//true
System.out.println(o instanceof Person);//true
System.out.println(o instanceof Student);//true
System.out.println(o instanceof String);//false
System.out.println(o instanceof Teacher);//false
子类对象转换成父类对象,可能会丢失一些自己本身的方法!!!
static关键字详解
匿名代码块 和 静态代码块
匿名代码块是在初始化对象的时候调用,在构造器之前
静态代码块是类加载的时候直接执行,永久仅仅只执行一次。
【实验验证】
准备:
Application.java
package oop;
import oop.demo07.Person;
public class Application {
public static void main(String[] args) {
Person person = new Person();
Person person1 = new Person();
}
}
Person.java
package oop.demo07;
public class Person {
{
System.out.println("start 匿名代码块");
}
static{
System.out.println("Person static 静态代码块");
}
public Person() {
System.out.println("Person 构造器");
}
}
静态导入包
正常情况下是【包名.函数名】
package oop;
public class Application {
public static void main(String[] args) {
System.out.println(Math.random());
}
}
静态导入包之后,可以直接使用该函数名
package oop;
import static java.lang.Math.random;
public class Application {
public static void main(String[] args) {
System.out.println(random());
}
}
抽象类
- 不能new,只能通过子类去实现它
- 抽象类是一个约束
- 抽象类中可以写普通的方法
- 抽象方法必须在抽象类中
- 抽象类 也有构造器
- 抽象类存在的意义:节省开发时间,提高开发效率,可扩展性比较高
【抽象类Action】
package oop.demo08;
//abstract 抽象类 类 extends 单继承
// 想要实现多继承 使用implements 接口可以多实现
public abstract class Action {
//约束
//abstract 抽象方法 只有方法名字没有方法实现
//抽象类的抽象方法,继承它的子类必须实现
public abstract void dosomething();
}
【A.java】
package oop.demo08;
//抽象类的所有方法,继承了它的子类,都必须要实现它的方法
public class A extends Action{
@Override
public void dosomething() {
}
}
接口
【demo】
package oop.demo09;
import java.sql.Time;
//实现接口的类,就要实现接口的方法
public class UserServiceImpl implements UserService, TimeService {
@Override
public void timer() {
}
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
}
接口的作用:
1)接口是一种约束
2)定义一些方法,不同的人实现
3)方法的默认修饰符(可以不写 系统自动添加)public abstract
4)接口中的常量都是:public static final 静态常量
5) 接口不能实例化(抽象类也不能被实例化)接口中没有构造方法
6)implements可以实现多个接口
7)实现接口的类必须重写接口中的方法
内部类
通过外部类来实例化内部类
内部类访问外部的私有属性、私有方法
一个Java文件只能有一个public class,但是可以有多个class
【Outer.java】嵌套形式的内部类
package oop.demo10;
public class Outer {
private int id;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
}
}
public class
public static class A//静态内部类
【非嵌套形式的内部类】
public class A{
}
class B{
}
【局部内部类】