面向对象的三大特性
封装、继承、多态
封装
概念:
1.封装是一种隐藏技术,可以让程序员将不想对外公开的方法、属性隐藏起来,同时可以隐藏方法实现细节。
2.可以让设计者和使用者分开,提高代码的安全性。
3.在Java中,使用private关键字来实现封装功能,
在想要被封装的属性或方法之前,加上private关键字就好了
package com.day8.privatetest;
public class Person {
//在属性前加上private
private String name;
private int age;
//构造方法也可以加上private,加上private后,无法直接调用
//构造方法来完成实例化
// 将来一般使用单例模式的时候,会这么做
public Person(){
}
public Person(String name, int age){
this.name=name;
this.age=age;
}
//编写get/set方法 快捷键(alt+insert 选getter and setter 回车)
//set方法,用来给私有化的成员属性赋值
//get方法,用来获取私有化成员属性值
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;
}
//在方法前加上private
private void show(){
System.out.println("这是一个核心方法,不想对外公开");
}
public void hello(){
System.out.println("这是一个对外公开的方法");
//在当前类中可以调用private修饰的方法
show();
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
私有化之后,怎么去给属性赋值?
使用set方法或全参构造
获取属性,只能用get方法
package com.day8.privatetest;
public class PersonTest {
public static void main(String[] args) {
//属性私有化之后i可以通过两种方法赋值
//1.如果类中存在全参构造方法,可以通过构造方法完成赋值
Person p1 = new Person("jack",20);
System.out.println(p1);
System.out.println(p1.getName()+"的年龄是"+p1.getAge());
//2.可以通过类的getter/setter方法赋值
//get/set方法其实就是类的成员方法,需要手动编写出来
Person p2 = new Person();
p2.setName("tom");
p2.setAge(22);
System.out.println(p2);
}
}
this关键字
1.this表示的是当前对象的意思,new出来的是谁,就表示谁
2.this可以用来调用成员变量、普通方法、构造方法
3.this调用构造方法的时候,只能放在第一行
this调用普通方法
this可以省略
this调用构造方法
无参构造写法是:this()
如果调用的是有参构造,写法就是 this(参数)
this调用构造的时候,不能产生循环调用
必须要写在其它构造方法的第一行
package com.day8.privatetest;
public class Demo01 {
public Demo01(){
//this();//只能在其他方法里调用,不能在自身,表示调用的是无参构造
this("jack");
System.out.println("无参构造1");
}
public Demo01(String name){
this(20);
System.out.println("参数为name的构造2");
}
public Demo01(int age){
//this调用普通方法,this可以省略
show();
System.out.println("参数为age的构造3");
}
public void show(){
System.out.println("普通方法4");
}
public static void main(String[] args) {
new Demo01();
}
}
包
包名的写法:
包名必须位于Java文件中的第一行,以package开头,后面跟上这个类所在项目的目录结构
包名的取名:以倒置的域名为取名方式
com.公司名.项目名.cotroller
com.公司名.项目名.service
······
包名不能以纯数字、关键字命名,一般包名都是小写的
其实就是项目中的不同文件夹,如果两个类在同一个文件夹下,则称他们属于一个包下; 如果不在同一个文件夹下,则称不属于同一个包。
如果想使用不同包下的类,必须要导包,导包用import
修饰符
访问修饰符:主要用来控制访问权限
public:公共的,任何位置,都可以访问到public修饰的类、方法、变量···
protected:受保护的,同包下的类,不同包下的子类可以访问
default:默认的,不写任何修饰符,就表示默认的,同包下的类可以访问
private:私有的,只有在当前类可以访问
package com.day8.privatetest;
public class Demo02 {
//public:公共的,任何位置,都可以访问到public修饰的类、方法、变量···
public int number1=100;
//protected:受保护的,同包下的类,不同包下的子类可以访问
protected int number2=200;
//默认的不能被其他包的访问
int number3=300;
//private:私有的,只有在当前类可以访问
private int number4=400;
}
package com.day8.test;
import com.day8.privatetest.Demo02;
public class Test extends Demo02{
public static void main(String[] args) {
//不同包下的子类
Demo02 demo02 = new Demo02();
System.out.println(demo02.number1);
//System.out.println(demo02.number2);
//System.out.println(demo02.number3);
//System.out.println(demo02.number4);
Test t = new Test();
System.out.println(t.number1);
System.out.println(t.number2);
//System.out.println(t.number3);
//System.out.println(t.number4);
}
}
package com.day8.privatetest;
public class Test {
public static void main(String[] args) {
Demo02 d = new Demo02();
System.out.println(d.number1);
System.out.println(d.number2);
System.out.println(d.number3);
//System.out.println(d.number4);
}
}
非访问修饰符:
static:静态的,修饰变量、方法、代码块
final: 最终的 ,修饰类型 、变量 、方法
abstract:抽象的,修饰类、方法
synchronized:同步的,修饰方法、代码块
static的使用
static表示静态的,修饰的内容,随着类的加载而加载
可以用来修饰成员变量、成员方法、代码块
代码块就是用花括号括起来的内容
1.static修饰成员变量,成为类属性,随着类的加载而加载,
将来可以通过类名直接调用,也可以通过对象名调用。
类属性被赋值后,可以被所有对象共享此属性值,可以达到共享数据的目的
将来如果某个类的属性,实例化对象后,属性值都是相同的常量值的话,
可以使用static修饰为静态常量,从而达到节省空间的目的。
package com.day8.statictest;
public class StaticDemo {
public static int number;//静态变量
public String name;
public static void main(String[] args) {
//静态变量可以通过类名直接调用
StaticDemo.number=100;
StaticDemo s1 = new StaticDemo();
s1.name="jack";
s1.number=200;
System.out.println(s1.number);
StaticDemo s2 = new StaticDemo();
s2.name="jack";
System.out.println(s2.number);
}
}
2.static修饰成员方法,就是类方法,随着类加载而加载,
将来可以通过类名直接访问静态方法。
静态方法中,将来只能调用静态的成员(成员变量或者成员方法)
package com.day8.statictest;
public class StaticDemo02 {
static int num1;
int num2;
static {
System.out.println("静态代码被调用了!");
}
public static void show(){
System.out.println(num1);
//静态方法中不能访问非静态的成员变量
//因为非静态的成员变量,随着对象创建而存在
//静态方法是随着类加载而加载的
//静态变量被调用后,对象没有创建的话,无法访问到非静态变量
//System.out.println(num2);
System.out.println("这是一个静态方法!");
}
public void say(){
}
public static void main(String[] args) {
StaticDemo02.show();
// StaticDemo02 s1 = new StaticDemo02();
// s1.show();
/*num++;
StaticDemo02 s1 = new StaticDemo02();
s1.num ++;
StaticDemo02 s2 = new StaticDemo02();
s2.num ++;
System.out.println(num);
*/
}
}
3.static修饰代码块,称为静态代码块,随着类的加载而加载,
随着类的调用而执行,只执行一次。
将来如果有属性的初始化操作,可以通过静态代码块完成属性的初始化
如果类中存在main方法,那么main方法执行的时候,类就会被调用,这个时候,类中的代码块也会执行。
如果没有main方法,那么只有当类内调用,或者实例化的时候,静态代码块才会被调用。
package com.day8.statictest;
public class StaticDemo03 {
//静态代码块
static {
int a=100;
System.out.println(a);
}
//构造方法
public StaticDemo03(){
System.out.println("无参构造");
}
//构造代码块
{
int i =300;
System.out.println(i);
}
{
int j =400;
System.out.println(j);
}
//静态代码块
static {
int b=200;
System.out.println(b);
}
public static void main(String[] args) {
//局部代码块
//100
//200
{
int i =500;
System.out.println(i);
//500
}
System.out.println("-------------");
StaticDemo03 d1 = new StaticDemo03();
//300
//400
System.out.println("-------------");
StaticDemo03 d2 = new StaticDemo03();
//300
//400
//无参构造
}
}
局部代码块、构造代码块、静态代码块 执行顺序?
局部代码块:方法中声明的代码块,
构造代码块:在类中的代码块,没有任何修饰的,随着构造方法被调用而执行,
调用一次,执行一次,按照顺序执行
静态代码块: