1.封装
封装是把过程和数据包围起来,对数据的访问只能通过指定的方式。
高内聚,低耦合
高内聚:类的内部数据操作细节自己完成,不允许外部干涉。
低耦合:只有少量的方法给外部使用。
属性私有 get 和 set 方法,在set 方法中可以设置一些判断条件,来确保数据的正确性。
封装的作用:
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一用户的调用接口,所有的方法都是get() 和set()
4.系统可维护性增强了
5.便于调用者的调用
封装的步骤:
1.使用private修饰需要封装的成员变量。
2.提供一个公开的方法设置或者访问私有的属性 get 和set 方法来设置和访问。
3.可以在set方法里设置条件,进行安全性的判断。
一、对象能在外部直接访问的:对象.属性 或者 对象.方法
public class Student{
public String name;
public void println(){
System.out.println(this.name);
}
}
public class Test{
public static void main(String[] args){
Student s = new Student();
s.name = "tom";//对象.属性 直接赋值
}
}
二、类中不会把类暴露在外部,而使用私有private关键字把数据隐藏起来,通过get()和set()两种方法来获取。
public class Student{
private String name;
public void setName(String name){//set负责给属性赋值
this.name = name;
}
public String getName(){//get负责返回属性的值
return this.name;
}
}
public class Test{
public static void main(String[] args){
Student s = new Student();
s.setName("tom");//只能通过setName()进行对名字的赋值
System.out.println(s.getName());//只能通过getNane()对名字进行调用
}
}
回顾方法的重载:相同的名字,参数不同。
例如:println(); println()方法名相同,但是参数有很多种,有double,int,float,char,Object,String,各种类型。
判断两个方法是否相同 : 看方法名;参数列表;
2.继承继承:ctrl + h 可以查看继承关系 --------- 以树结构的形式呈现
extands 继承本质是对某一批类的抽象,只有单继承。
继承是类和类之间的一种关系,此外还有依赖、组合、聚合关系。
继承关系的两个类,一个是子类,一个是父类,子类继承父类用extends来表示。
在java中所有的类都默认直接或间接的继承object类。
//继承的样式:
public class Student extends Person{
}
父类中所有的属性和方法都可以被子类继承。只要子类继承了父类,其父类中所有的方法都会拥有。
子类中继承了父类中的属性和方法,在子类中能不能直接使用这些属性和方法,是看在父类中的修饰符(public,protected,default,private).
在以上四种权限范围内,私有的东西不能被继承,只有private不能直接对象.属性 或者 对象.方法。其余public,protected,default都可以在其他类中访问到。在Teacher类中进行测试:
***************Person类中:*******************************
package oop.demo04;
public class Person {
private String name;
int age = 10;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void say(){
System.out.println("会说话");
}
}
*****************Student类*******************************
package oop.demo04;
public class Student extends Person {
private int id;
private char sex;
private double score;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
*******************Teacher类*******************************
package oop.demo04;
public class Teacher extends Person{
private int age;
char sex = '女';
protected int id = 456123;
public String name = "张三";
@Override
public int getAge() {
return age;
}
@Override
public void setAge(int age) {
this.age = age;
}
}
********************Application类 测试类*******************************
package oop.demo04;
public class Application {
public static void main(String[] args) {
// 在Student类中的测试:
// Student stu = new Student();
// stu.say();
// System.out.println(stu.age);
// stu.setName("张三");
// System.out.println(stu.getName());
Teacher tea = new Teacher();
tea.setAge(45);
System.out.println(tea.getAge());
System.out.println( tea.name);
System.out.println( tea.id);
System.out.println(tea.sex);
}
}
******************************测试结果:*******************************
45
张三
456123
女
3. Object类
java 中的每一个类都是"直接" 或者 "间接"的继承了Object类.
instanceof 属于
在Object类中,提供了一些方法被子类继承,那么就意味着,在java中,任何一个对象都可以调用这些被继承过来的方法。(因为Object是所以类的父类)
例如: toString 方法、equals方法、getClass 方法等
注:Object类中的每一个方法之后都会使用到.
4.super类super类代表父类,this类代表当前类。
举例1:子类调用父类的属性测试
************************************父类 Person类*******************************
public class Person {
protected String name = "父亲person";
}
************************************子类 Student类*******************************
public class Student extends Person {
private String name = "儿子student";
public void test(String name){
System.out.println(name);//当前参数传递值 在测试类中传入的值
System.out.println(this.name);//当前儿子类中的属性:儿子
System.out.println(super.name);//父类中的属性:父亲
}
}
***********************************测试类 Application类******************************
public class Application {
public static void main(String[] args) {
Student stu = new Student();
stu.test("测试名字" );
}
}
*********************************************测试结果:*******************************
测试名字
儿子student
父亲person
举例2: 子类调用父类的方法测试 但是如果父类的属性或者方法是私有的,子类中就无法调用。
***********************************父类 Person类 ***********************************
public class Person {
public void print(){
System.out.println("Person");
}
}
***********************************子类 Student类 ***********************************
public class Student extends Person {
public void print(){
System.out.println("Student");
}
public void test2(){
print();// Student 当前方法的值
this.print();// Student 本类中方法的值
super.print();// Person 父类方法的值
}
***********************************测试类 Application类*******************************
public class Application {
public static void main(String[] args) {
Student stu = new Student();
stu.test2();
}
*************************************测试结果 : *************************************
Student
Student
Person
举例3: 无参构造器的调用
1.调用一个对象先走无参构造器
2.先执行父类的构造器,再执行子类的构造器。原因是:在子类的构造器第一行里有隐形隐藏的父类无参构造器
***********************************父类 Person类 ************************************
public class Person {
public Person(){
System.out.println("父类无参构造器");
}
}
***********************************子类 Student类 ***********************************
public class Student extends Person {
public Student(){
//隐藏代码:调用了父类的无参构造
super();//只能在第一行出现 默认的,不写也调用
System.out.println("子类无参构造器");
}
}
***********************************测试类 Application类*******************************
public class Application {
public static void main(String[] args) {
Student stu = new Student();
}
}
*************************************测试结果 : *************************************
父类无参构造器
子类无参构造器
举例4: 子类无参调用父类有参构造器
***********************************父类 Person类 ************************************
public class Person {
//没有显性写出无参构造器
public Person(String name){
System.out.println("父类有参构造器");
}
}
***********************************子类 Student类 ***********************************
public class Student extends Person {
public Student(){
super("name");//调用父类有参构造器
System.out.println("子类无参构造器");
}
}
***********************************测试类 Application类*******************************
public class Application {
public static void main(String[] args) {
Student stu = new Student();
}
}
*************************************测试结果 : *************************************
父类有参构造器
子类无参构造器
Super 注意点:
-
super调用父类的构造方法,必须在构造方法的第一行。super();
-
super 必须只能出现在子类的方法或者构造方法中!
-
super 和 this不能同时调用构造方法!
this:
-
代表的对象不同。this代表本身调用者的对象。super代表父类对象的应用。
-
this();必须在构造器的第一行。
-
使用前提不同:this没有继承也可以使用,super只能在继承后才可以使用。
-
构造方法不同:this();调用本类的构造,super();调用父类的构造!
构造器使用:
1.调用构造器只能调用一个,要么调用父类,要么调用子类。
2.一个类默认构造器是无参构造器,只要重写有参构造器,无参构造器就得显性表示。
3.如果父类中没有显示表达无参构造器,在子类中要调用父类的构造器,可以调,不过必须调用父类的有参构造器。
5.方法的重写 override1.前提:需要有继承关系,子类重写父类的方法!
2.方法名必须相同
3.参数列表必须相同
4.修饰符:范围可以扩大但是不能缩小。public > protected > default > private
5.抛出异常:范围可以被缩小,但是不可以扩大。ClassNotFoundException(小) ---> Exception(大)
静态方法和非静态方法的区别很大!
1.在static修饰下重写: static静态方法:方法的调用只和左边定义的数据类型有关 static和类一起加载
***********************************父类 B类 ****************************************
public class B {
public static void print(){
System.out.println("B");
}
}
***********************************子类 A类 ****************************************
public class A extends B {
public static void print(){
System.out.println("A");
}
}
***********************************测试类 Application类*******************************
public class Application {
//在static修饰下 方法的调用只和左边定义的数据类型有关
public static void main(String[] args) {
A a = new A();
a.print(); //A
//父类的引用指向了子类
B b = new A();
b.print();//B
}
}
*************************************测试结果 : **************************************
A
B
非静态的方法才有重写
***********************************父类 B类 ****************************************
public class B {
public void print(){
System.out.println("B");
}
}
***********************************子类 A类 ****************************************
public class A extends B {
public void print(){
System.out.println("A");
}
}
***********************************测试类 Application类*******************************
public class Application {
public static void main(String[] args) {
A a = new A();
a.print();
//接收对象B
B b = new A();
b.print();
}
}
*************************************测试结果 : **************************************
A
A
重写都是方法的重写,和属性无关,方法体不同!
子类继承父类进行重写它的方法。必须是public修饰的,private不可以而且是非静态的,如果是static不可以重写。
为什么需要重写? 父类的功能子类不一定需要,或者不一定满足。 alt + Insert ---> override
6.多态动态编译:类型:可扩展性
多态性是指允许不同类的对象对同一消息作出响应。
对象,是具体的事物。类,是抽象的,是对对象的抽象。从代码运行角度考虑先有类后有对象。类是对象的模板。
一个对象的实际类型是确定的,但可以指向对象引用的类型有很多(父类或者有关系的类)
相同类域的不同对象,调用相同方法,表现出不同的结果。
一个对象的实际类型是确定的,new Student(), new Person(); new Student(); new Person();
指向对象的引用类型却是任意的可以是 Student,Person,Object. Student s1 = new Student(); Person s2 = new Student();//父类的引用指向子类对象 必须有关系 Object s3 = new Student(); //可以通过父类去new子类 // String s4 = new Student(); String 与 Student 没有关系 所以不可以
s2.方法(),在子类没有重写方法时走的还是父类的方法
s2.run();//虽然new Student(),但还是走的父类方法 因为子类继承了父类全部方法
s2.run();//如果子类重写父类的方法,那么执行子类的方法
s1.run();
多态的调用: 子类和父类都有的方法,子类没有重写父类的,就调用父类里的方法。如果子类重写了父类的方法,就调用子类的。 对象能执行那些方法,主要看对象左边的类型,和右边关系不大! 子类的引用和父类的引用不一样 子类能调用的方法是student里的,或者继承出来的方法。 父类型 可以指向子类,但是不能调用子类独有的方法 运行时和动态方法绑定 --- 因为之间存在类型转化
***********************************父类 Person类 **************************************
public class Person {
public void run(){
System.out.println("Person run");
}
}
***********************************子类 Student类 **************************************
public class Student extends Person {
@Override
public void run() {
System.out.println("Student run");
}
public void eat(){
System.out.println("eat");
}
}
***********************************测试类 Application类 *******************************
Student s1 = new Student();
Person s2 = new Student();//父类的引用指向子类对象 必须有关系
Object s3 = new Student(); //可以通过父类去new子类
s2.run();//虽然new Student(),但还是走的父类方法 因为子类继承了父类全部方法
s2.run();//子类重写父类的方法,执行子类的方法
s1.run();
((Student) s2).eat();//不能直接调用子类里特有的方法,Person里没有eat(); 高 --> 低 强制类型转换
*************************************测试结果 : **************************************
Student run
Student run
Student run
eat
多态注意事项:
-
多态是方法的多态,属性没有多态
-
父类和子类要有联系 类型转换异常 ! ClassCastException!
-
存在条件 : 必须有继承关系 方法需要重写,父类的引用指向子类对象! Father f1 = new Son();
方法不能重写:
-
static 修饰的方法,属于类,不属于实例
-
final 常量
-
private 方法,私有的方法也不可以被重写



