一、封装
在Java中面对对象是指宏观上把控整个事务的完成度以及事务走向。而面向对象三大特性中封装就是
将底层的实现方法抽离出来,变成一个类或方法,隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:
将变化隔离、便于使用、提高重用性、提高安全性
封装原则:
将不需要对外提供的内容都隐藏起来、把属性都隐藏,提供公共方法对其访问。
1.1、访问权限修饰符
在学习封装的过程中首先要了解到java中4种访问权限修饰符的用法
public: 修饰的人见人爱型 都能访问 被public修饰的方法、类、变量能被所有类可见
protected: 同包下可见 异包下子类可见
默认的: 不写 远亲不如近邻 同包下可见 异包下不可见
private: 自私自利 本类可见
注意:
ptivate是封装常用的修饰符,private代表私有的,它修饰的属性和方法只能本类可见。用private将成员变量私有化后,需要提供get()、set()方法,外界才能访问,提高对数据访问的安全性。
1.2、static
static表示静态的,用static修饰的变量叫静态变量,static修饰的方法称为静态方法,static修饰的代码块叫做静态代码块。
a)静态变量
static修饰的变量是静态变量,静态变量是属于类的,对所有对象共享,它在类初次加载时会被初始化只会执行一次,在内存中只有一个副本。非静态是属于对象的,在创建对象时才会被初始化,存在多个副本,各个对象拥有的副本互不影响。
b)静态方法
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
c)静态代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
示例:
package com.mage.var;
import java.util.Scanner;
public class Flower {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入一个数:");
int num =input.nextInt();
FlowerTool f =new FlowerTool();
boolean flag=f.flowerVar(num);
System.out.println(flag?"这是水仙花数":"这不是水仙花数");
System.out.println(f.flowerSum(num));
}
}
方法类:
package com.mage.var;
public class FlowerTool {
//判断是否为水仙花数
public static boolean flowerVar(int num) {
return num==flowerSum(num);
}
//求水仙花数
public static int flowerSum(int num) {
int num1=num;
int sum =0;
int length=length(num);
while(num1!=0) {
int bte = num1%10;
num1 =num1/10;
sum=sum+pow(bte,length);
}
return sum;
}
//求一个数的位数
private static int length(int num) {
int length=0;
while(num!=0) {
num = num/10;
length++;
}
return length;
}
//求一个数的位数次方
private static int pow(int bte,int length) {
int sum1=1;
for(int i=1;i<=length;i++) {
sum1=sum1*bte;
}
return sum1;
}
}
二、继承
1、什么是继承?
子承父业,将多个类中的共性再一次抽取,可以抽取为一个父类。父类的作用就是用来将一些重复的内容不再多次编写(提高代码复用性)
2、继承的编写:
子类 extends 父类,子类拥有父类中的所有属性和方法
3、继承的优势:
在一定程度上提高了代码的复用性
4、注意事项:
java中只支持单继承 一个子类有且只能有一个父类 复用性的提高是有限的
多继承好还是单继承好?
多继承 :
极大提高代码复用性 但是代码调用的复杂度也提升了
单继承:
代码调用的复杂度比较低,但是复用性比较有限
假设在应用场景中:
A->B 后期随着业务不断扩展,导致A需要继承C时一般的解决办法:A->B->C
但是该种解决办法随着后期业务的不断升级,导致整个继承连会变得极其复杂,既不利于后期维护以及拓展。能不能用继承就别用继承。
2.1、Super关键字
当创建子类对象时 会先执行父类的构造器。
Super:和this用法一样。
super.默认是可以省略的,和this.用法一样
super():调用父类的构造器,默认情况下调用的父类的无参构造器(默认情况下每个类中都存再一个无参构造器 哪怕不写也存在)
当父类中存在其他构造器时,无参构造器不存在,此时如果再子类中没有通过super()显示的指定调用的构造器会导致程序报错
在构造器中this()和super()不能同时出现,如果两个都不存在,默认是存在的super()。
2.2、重写
在子类中定义了和父类中同名的方法 我们将该方法称之为重写方法(覆盖)
为什么需要重写?
父类的功能不能满足子类的需求。子类在父类的基础上进行了扩展。
如何确定一个方法是重写方法?
在子类的方法上加入@Overried 注解 如果不报错 证明是重写
重写的前提:
一定要发生继承关系。并且子类的方法名和父类的方法名同名
参数列表要一样
返回类型要一样
示例:
public class Test03 {
public static void main(String[] args) {
//创建一个子类对象
S s = new S();
s.study();
s.marry();
s.work();
}
}
/**
* 爱情观
*
* @author wawjy
*
*/
class F{
String name;
public F() {
}
public int study() {
System.out.println("好好学习 时间观念及其严苛");
return 1;
}
public void marry() {
System.out.println("赶紧结婚 我要抱孙子");
}
public void work() {
System.out.println("赶紧去挣奶粉钱。。。。。");
}
}
class S extends F{
public S() {
}
@Override
public int study() {
System.out.println("开心很重要 开心的学习");
return 1;
}
}
三、多态
多态是指多种形态,就是同一操作(方法)作用于不同的对象时,可以有不同的解释,产生不同的执行结果
构成多态的前提条件:
-
1:继承关系
-
2:父类变量指向了子类对象
-
3:一定要有方法的重写
示例:package com.mage.oop;
public class Test02 {
public static void main(String[] args) {
Chinese ch = new Chinese();
eatRoom(ch);
En en = new En();
eatRoom(en);
}/* * public static void eatRoom(Chinese ch) { ch.eat(); } * * public static void eatRoom(En en) { en.eat(); } */ public static void eatRoom(Person person) {// Person person = ch; Person person = en; person.eat(); }
}
Person类:class Person{
public Person() {
}
public void eat() {
}
}
class Chinese extends Person{
private String name;
private int age;
public Chinese() {
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
public void eat() {
System.out.println(“用筷子吃饭”);
}
}
class En extends Person{
private String name;
private int age;
public En() {
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
public void eat() {
System.out.println(“用刀叉吃饭”);
}
}