面向对象(二)
面向对象(二)
Java的三大特性:封装、继承、多态
面向对象编程(Object-Oriented Programming, oOP)
面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
封装详解
属性私有:get/set
public class Student {
private String name;
private int age;
private char gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 120 || age < 0){
System.out.println("年龄错误!");
this.age = 0;
}else {
this.age = age;
}
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
if (gender !='男' && gender!='女'){
System.out.println("性别错误!");
this.gender = '#';
}else {
this.gender = gender;
}
}
}
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("小🐖");
System.out.println(s1.getName());
s1.setAge(20);
System.out.println(s1.getAge());
s1.setGender('女');
System.out.println(s1.getGender());
}
}
封装的作用:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统可维护增加了
继承
JAVA中类只有单继承,没有多继承!
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。
子类继承父类,使用关键字extends来表示。子类和父类之间,从意义上讲应该具有"is a"的关系.
public class Person {
//public
//protected
//default
//private
public int money = 10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
}
public class Student extends Person{
}
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();
System.out.println(student.money);
}
object类
https://www.runoob.com/java/java-object-class.html
https://blog.csdn.net/weixin_43232955/article/details/89705350
super方法
属性
public class Person {
protected String name = "longyu";
}
public class Student extends Person{
private String name = "lzc";
public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("龍屿");
}
}
方法
//父类
public class Person {
public void print(){
System.out.println("Person");
}
}
//子类
public class Student extends Person{
public void print(){
System.out.println("Student");
}
public void test1(){
print();
this.print();
super.print();
}
}
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test1();
}
}
子类能否继承父类私有属性和方法:
Java官方文档的解释:子类不能继承父类的私有属性,但是如果子类中公有的方法影响到了父类私有属性,那么私有属性是能够被子类使用的。
//父类
public class Person {
public Person() {
System.out.println("Person无参构造");
}
}
//子类
public class Student extends Person{
private String name = "lzc";
public Student() {
//隐藏代码
super();
System.out.println("Student无参构造");
}
}
//main方法
public class Application {
public static void main(String[] args) {
Student student = new Student();
}
}
对子类无参构造的调用,子类会自动调用父类的无参构造
super();调用父类的构造器必须放在子类的第一行
对方法的重写必须先写无参构造,否则无法子类无法调用,且子类无法写无参构造。(super默认调用父类的无参构造,否则super只能调用指定父类的有参方法)
super注意点:
1.super调用父类的构造方法,必须在构造方法的第一个!
2.super必须只能出现在子类的方法或者构造方法中
3.super和this不能同时调用构造方法!
this注意点:
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的应用
前提:
this:没有继承也可以使用
super:只能在继承条件才可以使用
构造方法
this():本类的构造
super():父类的构造!
方法重写
public class Application {
public static void main(String[] args) {
A a = new A();
a.test();
//父类引用指向子类
B b = new A();
b.test();
}
}
//重写都是方法的重写,和属性无关
public class B {
public void test(){
System.out.println("B=>test()");
}
}
//继承
public class A extends B{
//Override 重写
@Override//注解:有注释功能
public void test() {
//不能是私有的方法和属性
System.out.println("A=>test()");
}
}
重写注意点:需要有继承关系,子类重写父类的方法!非静态
1.方法名必须相同
2.参数列表列表必须相同
3.修饰符:范围可以扩大但不能缩小: public>Protected>Default>private
4.抛出的异常:范围,可以被缩小,但不能扩大;ClassNotFoundException --> Exception(大)
重写,子类的方法和父类必要一致;方法体不同!
为什么需要重写:
1.父类的功能,子类不一定需要,或者不一定满足!
快捷键Alt +Insert ; override;
多态
//父类
public class Person {
public void run(){
System.out.println("run");
}
}
//子类
public class Student extends Person{
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
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();
//对象能执行哪些方法。主要看对象左边的类型
((Student) s2).eat();//子类重写了父类的方法,执行子类的方法
s2.run();
s1.run();
s1.eat();
}
}
多态注意事项:
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系类型转换异常!classcastException !
3.存在条件:继承关系,方法需要重写,父类引用指向子类对象!Father f1 = new Son();
无法重写的方法:
1. static方法,属于类,它不属于实例
2.final 常量:无法改变
3.private 方法:私有的
instanceof关键字
https://www.cnblogs.com/ysocean/p/8486500.html
instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
引用上面的例子:
//Object > Person > Student
//Object > Person > Teacher
//Object > String
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(student instanceof String); //编译报错
//System.out.println(X instanceof Y);//编译是否通过 --->是否存在父子关系
类型转化
public void go(){
System.out.println("go");
}
//类型之间的转换: 基本类型转换
// 父 子
//高 低
Person obj = new Student();
//student将这个对象转换为Student类型,我们就可以使川Student类型的方法了!
Student student = (Student) obj;
student.go();
类型转换注意点:
1.父类引用指向子类的对象
2.把子类转换为父类,向上转换
3.把父类转换为子类,向下转型,强制转换;
4.方便方法的调用,减少重复的代码!简介
抽象,继承,多态! 抽象: ->接口?
static关键字详解
静态方法可以静态方法,静态方法调用普通方法,通过实例化对象来实现。
//static
public class Student {
private static int age; //静态变量
private double score; //非静态变量
public void run(){
}
public static void go(){
}
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(Student.age);
System.out.println(s1.age);
System.out.println(s1.score);
go();//类的加载顺序
// run();//无法调用
}
}
代码的执行顺序 静态代码块 > 匿名代码块 > 构造方法
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 person1 = new Person();
System.out.println("===========");
Person person2 = new Person();
}
}
//静态导入包
import static java.lang.Math.PI;
import static java.lang.Math.random;
public class Test {
public static void main(String[] args) {
System.out.println(random());
System.out.println(PI);
}
}
final 修饰后的类无法被继承
抽象类
- abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
- 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
- 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
- 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
- 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
//abstract 抽象类
//extends 单继承 接口 多继承
public abstract class Action {
//约束
//abstract ,抽象方法,只有方法名字,没有方法的实现!
public abstract void a();
}
//抽象类的所有方法,继承了它的子类,都必须要实现它的方法~
//除非子类也是抽象类,则需要子类的子类去实现
public abstract class A extends Action{
@Override
public void a() {
}
}
1、不能new这个抽象类,只能靠子类去实现它;约束!
2、抽象类中可以写普通的方法
3、抽象方法必须在抽象类中
抽象的抽象 -----> 约束
思考题?抽象类无法通过new 实现,那么抽象类存在构造器么?存在的意义?
抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已。在继承了抽象类的子类中通过super()或super(参数列表)调用抽象类中的构造方法。
https://blog.csdn.net/u011514810/article/details/51232673
接口的定义和实现
定义:接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
https://www.runoob.com/java/java-interfaces.html
//interface定义的关键字,接口都需要有实现类
public interface UserService {
//常量 public static final
int AGE = 99;
//接口中的所有定义的方法其实都是加象的public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
public interface TimerService {
void Timer();
}
public class UserServiceImplement implements UserService,TimerService{
@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.必须重写接口中的方法
内部类
内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。
https://www.cnblogs.com/chenssy/p/3388487.html
1.成员内部类
成员内部类也是最普通的内部类,它是外围类的一个成员,所以他是可以无限制的访问外围类的所有 成员属性和方法,尽管是private的,但是外围类要访问内部类的成员属性和方法则需要通过内部类实例来访问。
在成员内部类中要注意两点,第一:成员内部类中不能存在任何static的变量和方法;第二:成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。
2.局部内部类
它只能在该方法和属性中被使用,出了该方法和属性就会失效。
3.匿名内部类
?
4.静态内部类
1、 它的创建是不需要依赖于外围类的。
2、它不能使用任何外围类的非static成员变量和方法。