面向对象可以有利于对系统的宏观把控,将系统按各自的特点分割成不同的类别、子类,然后再以面向过程的思想进行微观实现。
本质:以类的方式组织代码,以对象的方式封装数据
代码的角度是先有类,后有对象,类是对象的模板;生活中则是先有对象,再抽象出类。
new,本质是调用构造器,分配内存空间
构造器,初始化对象
public class Person {
public Person(){
System.out.println("无参构造器");
}
public Person(String name){
System.out.println("有参构造器"+name);
}
}
高内聚:数据的操作在类的内部完成,不让外部知道和干涉
低耦合:仅暴露少量的接口供外部使用
属性私有,get/set
public class Person {
int age;
String name;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>=0||age<120){
this.age = age;
}else{
System.out.println("年龄不合法!");
}
}
}
外包 | 本包 | 子父类 | 本类 | |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | × | √ | √ | √ |
default | × | √ | × | √ |
private | × | × | × | √ |
public class Son extends Person {
public static void main(String[] args) {
//错误的访问父类的protected方法
//Person person = new Person();
//person.setAge();
//正确打开方式,通过创建子类对象来访问
Son son = new Son();
son.setAge(10);
}
}
?
new子类对象时,默认会调用父类以及祖父类...的无参构造器
package com.kuang.oop.Demo01;
public class Student extends Person{
//子类无参构造器
public Student() {
super();//调用父类构造器必须放在子类构造体第一行
System.out.println("子类无参执行");
}
//子类有参构造器
public Student(String name){
super(name);//可以显示调用父类有参构造,否则依然默认调用父类的无参构造
this.name=name;
System.out.println("子类有参");
}
根据需要,通过重写来对父类的方法进行扩展增强
方便方法的调用
父类(祖父类)引用指向子类对象,父类(祖父类)可调用子类独有的方法,但必须先进行强制类型转换(高转低,范围大的是高如:double>int ,Father>Son)
Father f = new Son();//称f为子类Son的上转型对象
/*
拆分出来可以看成是这样:
Son s = new Son();
Father f = s;
子类引用类型(低)转父类引用(高),向上转型不用强转,但会丢失子类独有的方法,即使是同名的属性或重写的方法,调用时也是调用父类的。并且无法调用父类私有的属性和方法,如被static、final、private修饰的属性和方法。
**/
((Son)f).sonEat();//想要调用子类独有的方法,必须将引用类型进行强转,向下转型
实例对象可调用的方法由引用类型决定
只有直接或间接继承,并且父类引用指向子类对象时,才能对父类引用进行强转
低-------------------------------------->高
byte-->short-->int-->long-->float-->double//能转换的前提是高数据类型范围完全包含低数据类型范围,如byte和char就不能相互转
char-->int-->long-->float-->double
运算中,不同数据类型要先进行数据类型转换,然后再计算
高转低(高容量转低容量)
可能导致溢出
可能导致精度丢失
(类型)变量名
int i = 128;
byte b = (byte)i;//输出结果b变成-128,因为强转后溢出
double d = 1.8;
int i2 = (int)d;//输出结果i2为1,截断,丢失精度
低转高
自动转换
int i = 1;
double d = i;//不用强制转换,输出结果d为1.0
多态是指方法的多态,属性没有多态
被static、final和private修饰的方法不能重写
真正的父类对象不能强转成子类对象;但真正的子类对象可以,实际是自动转换的。
Father f = new Father();
Son s = (Son)f;//报错,实际就是Son s = new Father()的写法是错误的
Son s = new Son();
Father f = (Father)s;//(Father)可不写,等价于Father f = new Son();
子类的上转型对象重新强制转换回子类对象时,子类原有的私有属性和方法依然是不可使用
public class Student extends Person{
private int age=5;
private void study(){
System.out.println("study");
}
}
========================================
public class Application {
public static void main(String[] args) {
Person s = new Student();
int age = ((Student)s).age;//报错,私有属性不可访问
((Student)s).study();//报错,私有方法不可访问
}
}
/*
通俗理解:
儿子想装爸爸---------上转型Person s = new Student();
被打回原型----------强制转换Student s =(Student)s;
儿子死鸭子嘴硬坚决不承认,不能暴露自己是儿子的特征--------不能使用原来私有的方法和属性
**/
能否进行判断,先决条件是引用类型跟参与判断的类是否具有父子关系,若无,则编译直接报错
//Object>Person>Student
//Object>Person>Teacher
Student s = new Student();
System.out.println(s instanceof String);//s与String没有父子关系,编译报错
System.out.println(s instanceof Teacher);//同上,报错
判断结果由对象类型是否属于参与判断的类决定
Student s = new Student();
Person p = new Student();
System.out.println(s instanceof Person);//True
System.out.println(s instanceof Object);//True
System.out.println(p instanceof Student);//False
System.out.println(s instanceof Teacher);//False
结果为True的时候,才可以进行强制转换,否则转换报错:ClassCastException
Person p = new Student();
System.out.println(p instanceof Student);//True
((Student)p).study();//强转成功并调用Student的方法
System.out.println(p instanceof Teacher);//False
((Teacher)p).teach();//强转失败,运行报错Exception in thread "main" java.lang.ClassCastException: com.kuang.oop.Demo01.Student cannot be cast to com.kuang.oop.Demo01.Teacher
//java改变Static修饰的属性,会影响类变量和其他实例变量的值
public class Application {
public static void main(String[] args) {
Person p1 = new Person();
System.out.println(p1.age);//10
p1.age=11;
Person p2 = new Person();
System.out.println(p2.age);//11
System.out.println(Person.age);//11
}
}
静态方法可以被继承,但不能被重写;private方法和属性也可以被继承,但子类不能直接进行访问和重写
java使用static来实现全局变量的概念,所有实例共享静态变量,任何实例对静态变量的改动,都会反馈到其他实例上
静态变量和静态方法可以直接通过类名进行访问,随着类的加载同时加载和分配内存空间
没有static修饰的变量为成员变量,随着对象的创建而产生,随着对象的消失而消失
静态方法的存在与对象无关,因此不能通过this或super的方式进行调用
静态方法只能访问其他静态方法或静态变量,非静态方法则无此限制
静态代码块、匿名代码块和构造器的加载过程:
main()程序入口-->父类的static代码块-->子类的static代码块-->父类的匿名代码块和构造器-->子类的匿名代码块和构造器
Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字
在Java中切记:static是不允许用来修饰局部变量
static块可以出现类中的任何地方(只要不是方法内部,记住,任何方法内部都不行),并且执行是按照static块的顺序执行的
子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过
原文:https://www.cnblogs.com/zuozs/p/14402551.html