面向对象编程(Object-Oriented Programming, OOP)
面向对象编程的三大特性: 封装、继承、多态
类名+方法名
public class Student{
//静态方法
public static void say(){
System.out.println("学生在讲话");
}
public static void main(String[] args){
Student.say();
say();
}
}
注意:因为在同一个类下,所以也可以直接写方法名。
实例化类+方法名
public class Student{
//非静态方法
public void say(){
System.out.println("学生在讲话");
}
public static void main(String[] args){
Student student = new Student();
student.say();
}
}
1>带有static关键词的方法或者变量可以直接通过类名+方法名/变量名获取
public class Demo01 {
private static String name = "Lihua";
private double score = 88.8;
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
System.out.println(Demo01.name);
System.out.println(demo01.name);
System.out.println(demo01.score);
}
}
2>带有static关键词的方法或变量是与类一起加载的
public class Demo02 {
public static void a(){
}
public void b(){
a();
}
}
因为方法a()是和类一起加载的,所以方法b()里可以直接调用a()
public class Demo02 {
public static void a(){
b(); //报错
}
public void b(){
}
}
因为方法b()在类实例化之后才存在,所以在方法a()里调用方法b()会报错。
3>静态代码块只执行一次
public class Demo03 {
//2 作用:赋初值
{
System.out.println("匿名代码块");
}
//1 只执行一次
static{
System.out.println("静态代码块");
}
//3
public Demo03(){
System.out.println("构造方法");
}
public static void main(String[] args) {
new Demo03();
System.out.println("------------------");
new Demo03();
}
}
输出:
静态代码块
匿名代码块
构造方法
------------------
匿名代码块
构造方法
4>静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Demo04 {
public static void main(String[] args) {
System.out.println(random()); //0.13545342469787336
System.out.println(PI); //3.141592653589793
}
}
public class Demo01 {
public static void change(int a ){
a = 10;
}
public static void main(String[] args) {
int a = 1;
System.out.println(a); //1
change(a);
System.out.println(a); //1
}
}
public class Demo02 {
public static void main(String[] args) {
Student student1 = new Student("小明");
Student student2 = new Student("小红");
//⼀个⽅法可以改变⼀个对象参数的状态。
Demo02.swap1(student1, student2);
System.out.println("-----------------------------");
System.out.println(student1.name); //小红
System.out.println(student2.name); //小明
}
public static void swap1(Student student1,Student student2){
String temp = student1.name;
student1.name = student2.name;
student2.name = temp;
System.out.println("-----------swap1-------------");
System.out.println(student1.name); //小红
System.out.println(student2.name); //小明
}
}
class Student{
String name;
int age;
public Student(String name){
this.name = name;
}
}
public class Demo03 {
public static void main(String[] args) {
Student student1 = new Student("小明");
Student student2 = new Student("小红");
//⼀个⽅法不能让对象参数引⽤⼀个新的对象
Demo03.swap2(student1, student2);
System.out.println("-----------------------------");
System.out.println(student1.name); //小明
System.out.println(student2.name); //小红
}
public static void swap2(Student student1,Student student2){
Student temp = student1;
student1 = student2;
student2 = temp;
System.out.println("-----------swap2-------------");
System.out.println(student1.name); //小明
System.out.println(student2.name); //小红
}
}
class Student{
String name;
int age;
public Student(String name){
this.name = name;
}
}
Java中类只有单继承,没有多继承!可以简单理解为:一个儿子只能有一个爸爸,但是一个爸爸可以有多个儿子。
public class Demo01 {
}
class Person{
private int money= 10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
}
//子类继承父类,就会拥有父类的全部方法
class Student extends Person{
}
class Teacher extends Person{
}
继承关系:Object -> Person -> Student
继承关系:Object -> Person -> Teacher
说明:在Java中,所有的类都直接或间接继承Object
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("蒲荷");
}
}
class Person{
protected String name = "LanTian";
}
//子类继承父类,就会拥有父类的全部方法
class Student extends Person{
private String name = "Puhe";
public void test(String name){
System.out.println(name); //蒲荷
System.out.println(this.name); //Puhe
System.out.println(super.name); //LanTian
}
}
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test();
}
}
class Person{
protected String name = "LanTian";
public void print(){
System.out.println("Person");
}
}
//子类继承父类,就会拥有父类的全部方法
class Student extends Person{
private String name = "Puhe";
public void print(){
System.out.println("Student");
}
public void test(){
print(); //Student
this.print(); //Student
super.print();//Person
}
}
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test();
}
}
class Person{
protected String name = "LanTian";
//私有的东西无法被继承!!!!!!!!!!!!!!!
private void print(){
System.out.println("Person");
}
}
//子类继承父类,就会拥有父类的全部方法
class Student extends Person{
private String name = "Puhe";
public void print(){
System.out.println("Student");
}
public void test(){
print(); //Student
this.print(); //Student
super.print();//报错!!!!!!!!!!!!!!
}
}
public class Application {
public static void main(String[] args) {
Student student = new Student();
}
}
class Person{
public Person(){
System.out.println("Person无参执行了");
}
protected String name = "LanTian";
public void print(){
System.out.println("Person");
}
}
//子类继承父类,就会拥有父类的全部方法
class Student extends Person{
public Student(){
//隐藏代码,调用了父类无参构造器
super(); //调用父类的构造器,必须要在子类构造器的第一行
System.out.println("Student无参执行了");
}
private String name = "Puhe";
public void print(){
System.out.println("Student");
}
}
输出
Person无参执行了
Student无参执行了
1>super注意点
①super调用父类的构造方法,必须在构造方法的第一个
②super必须只能出现在子类的方法或者构造方法中!
③super和this不能同时调用构造方法
2>super与this的区别
代表对象
this:本身调用者这个对象
super:代表父类对象的引用
前提
this:没有继承也可以使用
super:只能在继承条件下使用
构造方法
this:本类的构造
super:父类的构造
重写静态方法。方法的调用只和左边定义的数据类型有关。
import java.security.PublicKey;
public class Application {
public static void main(String[] args) {
//方法的调用,只和左边,定义的数据类型有关
A a = new A();
a.test(); //A=>test
B b = new A();
//父类的引用指向了子类
b.test(); //B=>test
}
}
//重写都是方法的重写,和属性无关
class A extends B{
public static void test(){
System.out.println("A=>test");
}
}
class B{
public static void test(){
System.out.println("B=>test");
}
}
重写非静态方法。
public class Application {
public static void main(String[] args) {
A a = new A();
a.test(); //A=>test
B b = new A();
//子类重写了父类的方法
b.test(); //A=>test
}
}
//重写都是方法的重写,和属性无关
class A extends B{
public void test(){
System.out.println("A=>test");
}
}
class B{
public void test(){
System.out.println("B=>test");
}
}
总结
重写:需要有继承关系,子类重写父类的方法
1.方法名必须相同
2.参数列表必须相同
3.修饰符:范围可以扩大但不能缩小:public > protected > default > private
4.抛出的异常:范围,可以被缩小,但不能扩大;ClassNotFoundException --> Exception(大)
为什么需要重写?
父类的功能,子类不一定需要,或者不一定满足!
import java.security.PublicKey;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//可以指向的引用类型就不确定了:父类的引用指向子类
//Student能调用的方法都是自己的或者继承父类的
Student s1 = new Student();
//Person父类型,可以指向子类,但不能调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
// s2.eat() //报错,eat()为子类中独有的方法
s1.eat(); //eat
}
}
class Student extends Person{
public void run(){
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
class Person{
public void run(){
System.out.println("run");
}
}
多态注意事项
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系;类型转换异常时会报ClassCastException
3.存在条件:继承关系,方法需要重写,父类引用指向子类对象 Father f1 = new Son();
补充 不能重写的情况
1.static方法,属性类,它不属于实例
2.final,常量
3.private方法
1>原理说明
X instanceof Y
首先,看编译能否通过。如果X和Y存在联系,则编译通过。
//例如,存在这样的继承关系,Object - > Person -> Student和Object - > Person -> Teacher
Person p = new Student();
System.out.println(p instanceof Teacher);//是可以编译通过的,因为p的类型是Person,而Person和Teacher是存在关系的。
然后,看X指向的实例对象是不是Y的子类或父类,然后判断对错;如果X指向的实例是Y的子类或同一个类,返回true;
//比如,还是上文的继承关系
Object object = new Student()
System.out.println(object instanceof Person);//返回true因为Student是Person的子类
System.out.println(object instanceof Student);//返回true,因为Student跟Student是同一个类。
如果X指向的实例是Y的父类,或者没有继承关系;
Object object = new Person();
System.out.println(object instanceof Student);//返回false,因为Person是Student的父类;
Person person = new Student();
System.out.println(person instanceof Teacher);//返回false,因为Student和Teacher没有继承关系。
2>例子
public class Test {
public static void main(String[] args) {
//Object -> String
//Obeject -> Person -> Student
//Obeject -> Person -> Teacher
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 Teacher); //false
System.out.println(object instanceof String); //false
System.out.println("----------------------------");
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); //编译不通过
System.out.println("----------------------------");
Student student = new Student();
System.out.println(student instanceof Student); //true
System.out.println(student instanceof Person); //true
System.out.println(student instanceof Object); //true
// System.out.println(student instanceof Teacher); //编译不通过
// System.out.println(person instanceof String); //编译不通过
System.out.println("----------------------------");
Person person1 = new Person();
System.out.println(person1 instanceof Student); //false
System.out.println(person1 instanceof Person); //true
System.out.println(person1 instanceof Object); //true
System.out.println(person1 instanceof Teacher); //false
// System.out.println(person1 instanceof String); //编译不通过
System.out.println("----------------------------");
Person p = new Student();
System.out.println(p instanceof Teacher); //false
Object o = new Person();
System.out.println(o instanceof Student); //false
}
}
class Person{
}
class Student extends Person{
}
class Teacher extends Person{
}
类型之间的转化
子类转换为父类,可能会丢失自己本来的一些方法!
1>抽象类
//类extends,单继承,接口可以多继承
public abstract class Action {
//abstract,抽象方法,只有方法名字,没有方法实现
public abstract void doSomething();
//1.不能new这个抽象类,只能靠子类去实现它
//2.抽象类中可以写普通的方法和抽象方法
//3.抽象方法必须在抽象类中
//4.抽象类可以有构造器,需要通过构造链来调用
}
2>接口
接口的定义
public interface UserService {
//常量:默认使用public static final修饰
int AGE = 99;
//接口中定义的所有方法默认使用public abstract修饰
void add();
void delete();
void update();
void query();
}
接口的实现
public class UserServiceImpl implements UserService{
@Override
public void add() {
// TODO Auto-generated method stub
}
@Override
public void delete() {
// TODO Auto-generated method stub
}
@Override
public void update() {
// TODO Auto-generated method stub
}
@Override
public void query() {
// TODO Auto-generated method stub
}
}
接口不能被实例化,接口中没有构造方法;implements可以实现多个接口;必须要重写接口中的方法。
学习资料
1.【狂神说Java】Java零基础学习视频通俗易懂