Skip to main content
CleanCodeMastery

Pull Up Field: One Notice Board for Information Everyone Shares

Learn the Pull Up Field refactoring with a school notice-board story — move a field that every subclass duplicates into the superclass, with safe steps in TypeScript and C#, IDE support, and the pull-up vs push-down direction guide.

26 min read Updated June 11, 2026beginner
refactoringpull up fieldinheritancesuperclassduplicate codetypescriptcsharp

🏫 One address, three notice boards

Come with me to Sunrise Public School. Class 7 has three sections — 7A, 7B, and 7C. Each section has its own notice board hanging beside the classroom door. Downstairs, near the entrance, the main school office has one big notice board for the whole school. The office is run by the head clerk, Mr. Sharma, a quiet man who knows every notice on that board by heart.

The class teachers are part of this story too. Mrs. Iyer looks after 7A, Mr. Bose looks after 7B, and Ms. Fernandes looks after 7C, the sports section. Above all of them sits the Headmistress, Dr. Meena Kulkarni, who you will meet again and again in this series, because she is the person who keeps fixing the school's information problems — and every fix she makes is secretly a refactoring.

Some years ago, the sections started a pen-pal project. Students wrote letters to children in other cities, and the reply address had to be written on every envelope. So Priya, the monitor of 7A, neatly copied the full school address onto 7A's notice board. Arjun, the monitor of 7B, did the same on 7B's board. Meera, the monitor of 7C, did it too. Three boards, three hand-written copies of the same address. Nobody thought this was a problem. Why would they? Each monitor was just being helpful.

For a while, nothing went wrong. Then the postal department changed the area's PIN code. Mr. Sharma updated the office records the same afternoon — that is his job, and he did it perfectly. Priya heard about it from Mrs. Iyer and corrected 7A's board. Meera corrected 7C's board the next morning. But Arjun was absent that whole week with fever, and nobody else in 7B felt it was their board to touch.

For the next two months, every letter from 7B carried the old PIN code. Replies bounced back. Pen-pals in Chennai thought the 7B students had stopped writing. The 7B students thought their pen-pals had forgotten them. Mr. Bose only discovered the truth when a bundle of returned envelopes landed on his desk, all stamped addressee not found. All this sadness, because one copy out of three was not updated.

Dr. Kulkarni fixed it with one simple rule, announced at Monday assembly: "The school address is the same for every section. It will be written once, on the main office board, and Mr. Sharma alone will maintain it. Section boards will only carry things that belong to that section alone — the class timetable, the class teacher's name, the section's duty roster."

Do you see the idea? Information that is shared by everyone should live in one shared place, upstairs. Information that belongs to one section only stays on that section's board.

In code, the section boards are subclasses, and the main office board is the superclass. When every subclass declares its own copy of the same field, we move that field up into the superclass. This refactoring is called Pull Up Field.

Here is the whole painful-then-peaceful experience from Mr. Sharma's point of view, drawn as a journey:

Figure 1: The head clerk's journey before and after the address moved to one board

Look at the satisfaction scores. Before the fix, every update is a tiring round of the building with a real chance of missing a board. After the fix, one calm edit and the whole school is correct.

📌 What is Pull Up Field?

Pull Up Field is one of the simplest refactorings in Martin Fowler's Refactoring catalog, from the family that deals with generalization — that is, tidying up parent-child class relationships. The rule is short:

When two or more subclasses declare the same field — the same piece of information, with the same meaning — delete the copies and declare the field once in their common superclass.

Why do such duplicate fields appear at all? Because class hierarchies usually grow from the bottom. A developer writes SectionSevenA and gives it the fields it needs. Later, someone writes SectionSevenB, often by copy-pasting, and the same fields appear again. Then SectionSevenC arrives. Nobody planned the duplication; it just collected, the way three monitors each copied the address without ever discussing it with each other or with Mr. Sharma.

The trouble is exactly the PIN-code trouble. Three declarations of "the same thing" can quietly drift apart. One subclass calls it schoolAddress, another calls it address. One initializes it, another forgets. When the value's type or meaning must change, you must remember to change it in every subclass — and the compiler will not remind you about the copy you missed, just as nobody reminded the absent Arjun.

There is a second, bigger reason to pull the field up. While the data sits scattered in the subclasses, the superclass cannot host any behaviour that uses it. A shared printEnvelope() method cannot live in the parent if the address it needs lives only in the children. Pull Up Field hands the parent the data, and that unlocks the next refactoring, Pull Up Method, which is usually the real prize.

💡

One-line summary: Pull Up Field moves a field that every subclass duplicates into the superclass, so the shared information is declared once — like writing the school address on the main office board instead of on three section boards.

College corner: what the Headmistress enforced is the DRY principleDon't Repeat Yourself — applied to state in an inheritance hierarchy. DRY is often quoted as "don't write the same code twice", but its real statement is sharper: every piece of knowledge should have a single, authoritative representation in the system. The school address is one piece of knowledge; three boards meant three representations, and the system had no single source of truth. Pull Up Field restores a single authoritative representation for shared state, the same way normalization does for database columns. Keep that parallel in mind — duplicated subclass fields are to OOP what denormalized, drifting columns are to a database.

One more thing before we go on. Pull Up Field has an exact opposite called Push Down Field. Pull Up moves a field up because everyone shares it. Push Down moves a field down because only some children need it. The whole family of hierarchy moves fits on one small map:

Figure 2: The family of hierarchy moves and the one rule behind all of them

We will compare the two directions properly in the benefits section.

🔍 When do we need it?

Watch for these signs in your codebase:

  • The same field appears in two or more sibling subclasses. Same type, same purpose, often even the same comment — the classic shape of Duplicate Code, only this time it is duplicated state, not duplicated logic.
  • The fields have slightly different names but one meaning. schoolAddress in 7A's class, address in 7B's, schoolAddr in 7C's. A reader must open three files and compare to discover that these are the same concept. That detective work is a cost paid by every future reader.
  • A change had to be made in several places. If a recent task — change the field's type, rename it, change its default — made you edit three subclasses with the same edit, the field is begging to be pulled up.
  • You want to pull up a method but it will not compile in the parent. A method that reads this.schoolAddress cannot move to the superclass while the field lives below. Pull Up Field is the standard preparation step before Pull Up Method and Pull Up Constructor Body.

And here is the sign that you should not do it:

  • Only some subclasses use the field. If 7C alone needs swimmingPoolTimings, hoisting it to the parent forces 7A and 7B to carry information they never touch. That is the road to Refused Bequest — children inheriting things they do not want. For shared-by-all data, pull up; for some-children-only data, keep it down (or push it down if it already crept up).

A simple test before you pull anything: ask, "Does this field mean exactly the same thing for every subclass, today and most likely tomorrow?" If the honest answer is yes, pull it up. If the answer is "well, mostly, except for…", stop and think again. Two fields that merely share a name but carry different meanings must stay separate — merging them would build a false abstraction, which is worse than a little duplication.

The decision is really a position on two axes — how many subclasses use it and where it currently lives — and our school address sits squarely in the "pull up now" corner:

Figure 3: Placing the school address field on the pull-up versus push-down map

Read the map like this: our address field is used by all sections (far right) but currently lives in the subclasses (low) — that is the "pull up now" zone. After the refactoring, the same dot slides straight up into "healthy in base" and stays there.

👀 Before and after at a glance

Here is the school in TypeScript, the way it looked during the PIN-code disaster. Each section class keeps its own copy of the shared facts:

// BEFORE: the same fields declared three times
abstract class Section {
  // the office board is empty — it knows nothing!
}
 
class SectionSevenA extends Section {
  protected schoolAddress = "12 Lake Road, Pune 411001"; // Priya's copy
  protected classTeacher = "Mrs. Iyer";
}
 
class SectionSevenB extends Section {
  protected address = "12 Lake Road, Pune 411001";       // Arjun's copy, different name!
  protected classTeacher = "Mr. Bose";
}
 
class SectionSevenC extends Section {
  protected schoolAddress = "12 Lake Road, Pune 411038"; // Meera's copy — already drifted!
  protected classTeacher = "Ms. Fernandes";
}

Look closely at 7C. Its copy already carries a different PIN code — 411038 instead of 411001. Nobody decided this; the copies simply drifted, exactly like the notice boards. And 7B quietly renamed the field, so a search for schoolAddress will not even find it.

After Pull Up Field:

// AFTER: shared facts live once, in the parent
abstract class Section {
  protected schoolAddress = "12 Lake Road, Pune 411001"; // declared ONCE
}
 
class SectionSevenA extends Section {
  protected classTeacher = "Mrs. Iyer";   // only section-specific facts remain
}
 
class SectionSevenB extends Section {
  protected classTeacher = "Mr. Bose";
}
 
class SectionSevenC extends Section {
  protected classTeacher = "Ms. Fernandes";
}

The address is written once, on the office board. Each section board keeps only what truly belongs to that section: its own class teacher. When the PIN code changes again, the fix touches one line, and Mr. Sharma is the only person who needs to know.

The class diagrams make the movement easy to see:

Figure 4: Before — every section class declares its own copy of the school address
Figure 5: After Pull Up Field — the shared field moves up and is declared exactly once

Before the move, the duplication is spread evenly across the three sections — every section carries an equal share of the problem:

Figure 6: Before the refactoring, each section holds one of the three duplicate copies

After the move, that pie collapses to a single slice — the superclass — which is exactly the point.

🪜 Step-by-step, the safe way

Pull Up Field looks like a one-minute job, and often it is. But the safe path has a fixed order, and skipping steps is how "one-minute jobs" turn into evening-long debugging sessions. The overall flow is the one Dr. Kulkarni used:

Figure 7: Three duplicated boards converge into one office board

Here is the recipe in full.

  1. Confirm the fields really mean the same thing. Open every subclass. Check the type, the initial value, and — most importantly — the meaning. schoolAddress in all three sections means "the address of Sunrise Public School", so they match. If 7C's field had meant "address of the sports annexe", it would only look similar, and pulling up would be wrong.

  2. Give all copies one common name first. 7B's field is called address. Rename it to schoolAddress inside 7B, update every reference within that class, and run the tests. Renaming before moving keeps each change tiny and checkable:

    // INTERMEDIATE STEP: same name everywhere, nothing moved yet
    class SectionSevenB extends Section {
      protected schoolAddress = "12 Lake Road, Pune 411001"; // was: address
      protected classTeacher = "Mr. Bose";
    }
  3. Resolve any drifted values. 7C's copy holds PIN 411038. Is that a stale leftover or a real difference? Ask, check, decide. In our story it was simply never updated — a genuine bug that this refactoring just found for free. Fix it so all copies hold the same value. If the difference had been intentional, the field is not truly shared, and you should stop here.

  4. Declare the field in the superclass. If the subclass copies were private, the parent's version must be at least protected, otherwise the subclasses cannot see it. (In TypeScript and C#, protected means "me and my children can use it".)

  5. Delete the field from one subclass. Compile. Test. Remove schoolAddress from SectionSevenA only. The subclass now inherits the parent's copy, and all its old code keeps working. Run the test suite.

  6. Repeat for each remaining subclass, one at a time. Delete from 7B, test. Delete from 7C, test. Working in small bites means that if a test fails, you know exactly which deletion caused it.

  7. Optionally, hide the field behind an accessor. Refactoring Guru suggests following up with Self-Encapsulate Field — let subclasses reach the data through a getter rather than touching the field directly. This keeps the parent free to change how the value is stored later.

The lifecycle of the field through these steps fits a tiny state machine — and noticing the Verified state is the most important part:

Figure 8: The field's journey from duplicated to hoisted to verified
⚠️

Run the tests after every single subclass you touch, not once at the end. If you delete all three copies in one go and a test fails, you have three suspects. If you delete one copy at a time, you always have exactly one. Refactoring's safety comes from small steps with green tests in between — that is the whole trick.

College corner: step 4 hides a real design trade-off. Making the parent field protected widens its visibility: now every present and future subclass can read and write it directly, which couples all of them to the parent's storage decision. Many style guides (and tools like SonarQube) flag protected mutable fields for exactly this reason. The disciplined alternative is a private field in the parent with a protected getter — subclasses can read the shared fact but cannot scribble on it. You pay a few extra lines for a much smaller mutation surface. When the field is conceptually read-only (a school address rarely changes from inside a section), prefer the getter form.

✉️ How the runtime sees it, message by message

It is worth pausing to see what actually happens at runtime after the pull-up. When a section object is built and later asked for an envelope label, the address is fetched from the inherited parent state — there is no copying at all:

Figure 9: After the pull-up, the subclass reads the one shared copy from the base

This is the precise technical meaning of "one board upstairs": the subclass does not have an address; it reaches up for the single one the base class holds. There is nothing left to drift.

🏗️ A bigger real-life example

Let us give Sunrise School a slightly more realistic notice-board system. Before refactoring, each section class repeats three shared facts — address, phone number, and principal's name — alongside its genuinely own data:

// BEFORE: three shared facts, copied into every section
abstract class Section {}
 
class SectionSevenA extends Section {
  protected schoolAddress = "12 Lake Road, Pune 411001";
  protected schoolPhone = "020-2553-1100";
  protected principalName = "Dr. Meena Kulkarni";
  protected classTeacher = "Mrs. Iyer";
  protected studentCount = 38;
 
  envelopeLabel(): string {
    return `Class 7A, ${this.schoolAddress}`;
  }
}
 
class SectionSevenB extends Section {
  protected schoolAddress = "12 Lake Road, Pune 411001";
  protected schoolPhone = "020-2553-1100";
  protected principalName = "Dr. Meena Kulkarni";
  protected classTeacher = "Mr. Bose";
  protected studentCount = 41;
 
  envelopeLabel(): string {
    return `Class 7B, ${this.schoolAddress}`;
  }
}
 
class SectionSevenC extends Section {
  protected schoolAddress = "12 Lake Road, Pune 411001";
  protected schoolPhone = "020-2553-1100";
  protected principalName = "Dr. Meena Kulkarni";
  protected classTeacher = "Ms. Fernandes";
  protected studentCount = 35;
 
  envelopeLabel(): string {
    return `Class 7C, ${this.schoolAddress}`;
  }
}

Count the duplication: three shared fields × three sections = nine declarations for three facts. If the school gets a new principal, that is three edits. New phone number, three more. And notice the envelopeLabel() methods — nearly identical too, but we cannot move them up yet, because the address they read lives in the children.

Now we pull the three shared fields up, one field at a time, testing after each:

// AFTER: shared facts upstairs, section facts downstairs
abstract class Section {
  protected schoolAddress = "12 Lake Road, Pune 411001";
  protected schoolPhone = "020-2553-1100";
  protected principalName = "Dr. Meena Kulkarni";
 
  // Now that the data lives here, shared behaviour CAN live here too.
  envelopeLabel(): string {
    return `${this.sectionName()}, ${this.schoolAddress}`;
  }
 
  protected abstract sectionName(): string;
}
 
class SectionSevenA extends Section {
  protected classTeacher = "Mrs. Iyer";
  protected studentCount = 38;
  protected sectionName(): string { return "Class 7A"; }
}
 
class SectionSevenB extends Section {
  protected classTeacher = "Mr. Bose";
  protected studentCount = 41;
  protected sectionName(): string { return "Class 7B"; }
}
 
class SectionSevenC extends Section {
  protected classTeacher = "Ms. Fernandes";
  protected studentCount = 35;
  protected sectionName(): string { return "Class 7C"; }
}

Nine declarations became three. And see what happened to envelopeLabel(): the moment the address moved upstairs, the duplicated method could follow it. That second move is Pull Up Method, the subject of the next post — and this is the most important lesson of this page. Pull Up Field is rarely the goal. It is the door-opener. Data first, then behaviour.

The maintenance arithmetic also changes shape. Suppose a shared fact changes — new principal, new PIN code, new phone number. How many class bodies must someone edit?

Figure 10: Edits needed when one shared fact changes, before and after the pull-up

Three edits collapse to one — and the deeper win is not the saved typing, but the removed chance of forgetting. The 7B disaster was never about effort; it was about a copy nobody remembered.

🐍 The same idea in Python

Python has no protected keyword, but the convention of a single-underscore prefix plays the same role, and the move is identical:

# BEFORE: each section class repeats the shared fact
class Section:
    pass
 
class SectionSevenA(Section):
    def __init__(self):
        self._school_address = "12 Lake Road, Pune 411001"  # copy 1
        self._class_teacher = "Mrs. Iyer"
 
class SectionSevenB(Section):
    def __init__(self):
        self._school_address = "12 Lake Road, Pune 411001"  # copy 2
        self._class_teacher = "Mr. Bose"
 
 
# AFTER: declared once, inherited by all
class Section:
    SCHOOL_ADDRESS = "12 Lake Road, Pune 411001"  # one class-level copy
 
class SectionSevenA(Section):
    def __init__(self):
        self._class_teacher = "Mrs. Iyer"
 
class SectionSevenB(Section):
    def __init__(self):
        self._class_teacher = "Mr. Bose"

Notice the Python-flavoured bonus: because the address is the same for every instance as well as every subclass, it can become a class attribute (SCHOOL_ADDRESS) rather than an instance attribute — Python's natural way of saying "this fact belongs to the type, not to each object". Every instance of every section reads the same single value through normal attribute lookup, which walks up the class hierarchy exactly like a student walking downstairs to the office board.

💼 The same refactoring in C#

The idea is identical in C#; only the spelling changes. Before:

// BEFORE: every section carries its own copy
abstract class Section { }
 
class SectionSevenA : Section
{
    protected string _schoolAddress = "12 Lake Road, Pune 411001"; // copy 1
    protected string _classTeacher = "Mrs. Iyer";
}
 
class SectionSevenB : Section
{
    protected string _schoolAddress = "12 Lake Road, Pune 411001"; // copy 2
    protected string _classTeacher = "Mr. Bose";
}

After pulling the field up:

// AFTER: one protected field in the base class
abstract class Section
{
    protected string _schoolAddress = "12 Lake Road, Pune 411001"; // declared once
 
    public string EnvelopeLabel() => $"{SectionName}, {_schoolAddress}";
 
    protected abstract string SectionName { get; }
}
 
class SectionSevenA : Section
{
    protected string _classTeacher = "Mrs. Iyer";
    protected override string SectionName => "Class 7A";
}
 
class SectionSevenB : Section
{
    protected string _classTeacher = "Mr. Bose";
    protected override string SectionName => "Class 7B";
}

Two C#-specific notes:

  • Visibility: if the subclass fields were private, the base-class version must become protected (or private with a protected property around it). Many C# teams prefer exposing a protected property rather than a raw field — protected string SchoolAddress { get; } — because properties can later add validation or change storage without breaking subclasses.
  • Initialization: if subclass constructors were setting this field from parameters, the duplicated assignment lines are your next target — that is exactly what Pull Up Constructor Body handles, two posts from now.

🛠️ IDE support

Good news: you rarely have to do this by hand.

  • IntelliJ IDEA, Rider, PhpStorm (JetBrains family): select the field, then Refactor → Pull Members Up…. A dialog lists the class's members with checkboxes; tick the field, choose the destination superclass, and the IDE moves the declaration and removes the subclass copies. The same dialog drives the inverse, Push Members Down. JetBrains' documentation describes Pull Members Up exactly as our story does — a tool to "get rid of duplicate code" by moving identical fields and methods to a superclass.
  • Visual Studio (C#): place the cursor on the member, press Ctrl+. to open Quick Actions and Refactorings, and choose Pull members up to base type. A dialog lets you pick which members go up and to which base type. There is also "Pull member(s) up to new base class," which creates the superclass for you when none exists yet.
  • ReSharper: Refactor → Pull Members Up with conflict checking — it warns if the moved member would clash with something already in the base.
  • Eclipse (Java): Refactor → Pull Up… offers the same member-selection dialog.

One honest caution: the tool moves the declaration mechanically, but it cannot judge meaning. The IDE will happily merge schoolAddress ("school's postal address") with a same-named field that means something different. Steps 1–3 of our safe recipe — confirming meaning, unifying names, resolving drifted values — remain human work. Tools are Mr. Sharma's ladder and pins; deciding which notice belongs on which board is still the Headmistress's call.

⚖️ Benefits and risks

BenefitsRisks / costs
One declaration instead of N — a change to the field's name, type, or default touches one lineIf the fields only looked alike but meant different things, merging them creates a false abstraction
Copies can no longer drift apart (no more 7C with a stale PIN code)A private subclass field usually becomes protected, widening its exposure
The superclass gains the data it needs to host shared behaviour — unlocks Pull Up MethodIf only some subclasses use the field, pulling up plants a Refused Bequest smell
The hierarchy reads honestly: shared things upstairs, special things downstairsSubclasses become slightly more coupled to the parent's data layout (soften with accessors)
Bugs hiding in drifted copies get discovered during the mergeAlmost none otherwise — this is one of the lowest-risk refactorings in the catalog

Now, the direction question. Pull Up Field and Push Down Field are exact inverses, and both exist because both mistakes happen in real codebases. The compass fits in one small table:

Who uses the field?Where it should liveRefactoring to apply
All (or almost all) subclassesThe superclass — the office boardPull Up Field
Exactly one subclassThat subclass — its own section boardPush Down Field
A natural group of subclassesAn intermediate parent for that groupExtract Subclass / intermediate class
Nobody anymoreNowhere — delete itRemove Dead Code

The two refactorings are not rivals; they are the same tidying instinct applied in opposite directions. A healthy hierarchy uses both over its lifetime, the way the school sometimes moves a notice up to the office board and sometimes moves one down to a single section's board.

College corner: there is a quieter principle underneath the compass — the Liskov Substitution Principle (LSP). A field on the superclass is a structural promise: any Section object, no matter which concrete subclass, meaningfully has this data. Code written against the parent type relies on that promise. Pull up a field that some children do not honour, and parent-typed code starts handling objects whose inherited state is meaningless — substitutability is technically intact but semantically broken. So the question "does every subclass genuinely share this field?" is really the question "can I strengthen the parent's contract without lying about any child?"

🩺 Which smells does it cure?

SmellHow Pull Up Field helps
Duplicate CodeThe primary cure — N identical field declarations collapse into one
Shotgun SurgeryA change to the shared fact now touches one class instead of every subclass
Refused BequestIndirect: knowing when not to pull up (only-some-use-it fields) prevents creating this smell
Blocked generalizationNot a named smell, but the everyday situation where duplicated methods cannot move up because their data is stuck below — Pull Up Field unblocks Pull Up Method

📦 Quick revision box

+--------------------------------------------------------------+
|                   PULL UP FIELD — REVISION                   |
+--------------------------------------------------------------+
| Story    : School address copied on 3 section boards;        |
|            7B's copy went stale -> letters bounced.          |
|            Fix: write it ONCE on the main office board.      |
|                                                              |
| Move     : Field duplicated in subclasses  --->  superclass  |
|                                                              |
| Do it when : EVERY subclass shares the same-meaning field    |
| Don't when : only SOME subclasses use it (-> Refused         |
|              Bequest; consider Push Down Field instead)      |
|                                                              |
| Safe steps : same meaning? -> same name -> fix drift ->      |
|              declare in parent (protected) -> delete from    |
|              subclasses ONE AT A TIME, testing each time     |
|                                                              |
| Inverse    : Push Down Field (shared->up, special->down)     |
| Unlocks    : Pull Up Method, Pull Up Constructor Body        |
| Cures      : Duplicate Code (in state declarations)          |
+--------------------------------------------------------------+

✏️ Practice exercise

Time to be the Headmistress. Here is a small hierarchy from the school's library software:

abstract class LibraryMember {}
 
class StudentMember extends LibraryMember {
  protected libraryName = "Sunrise School Library";
  protected maxBooks = 2;
  protected finePerDay = 1; // rupees
}
 
class TeacherMember extends LibraryMember {
  protected libName = "Sunrise School Library";   // different name!
  protected maxBooks = 6;
  protected finePerDay = 1;
}
 
class GuestMember extends LibraryMember {
  protected libraryName = "Sunrise Public School Library"; // drifted!
  protected maxBooks = 1;
  protected finePerDay = 5;  // guests pay more
}

Your tasks:

  1. Decide which fields should be pulled up and which must stay down. (Hint: maxBooks differs by member type with intention — is that truly shared state, or per-class policy? And finePerDay matches for two classes but not the third — what does the direction compass say?)
  2. libName in TeacherMember needs what preparation step before any move?
  3. libraryName in GuestMember has drifted. Is the drift a bug or a real difference? Write down what you would check before merging. (Who would you ask at Sunrise School? Probably Mr. Sharma — he keeps the official records.)
  4. Perform the refactoring in the safe order: rename, fix drift, declare in LibraryMember, then delete from one subclass at a time, "running tests" between steps.
  5. Bonus: after the pull-up, write a membershipCardLabel() method on the superclass that uses the shared field — and notice that yesterday this method had nowhere to live. You have just experienced why Pull Up Field is called an enabling refactoring.

When you can explain to a friend why libraryName goes up but maxBooks stays down, you have understood Pull Up Field — and you are ready for its big sibling, Pull Up Method.

Frequently asked questions

What exactly does Pull Up Field do?
When two or more subclasses declare the same field — the same piece of information with the same meaning — Pull Up Field deletes those copies and declares the field once in the common superclass. All subclasses then inherit the single shared copy, so there is one place to read it and one place to change it.
What if the duplicated fields have different names in different subclasses?
Rename them first. Give every copy the same, clearest name and update all references, running tests after each rename. Only when the fields clearly mean the same thing and carry the same name should you move the single declaration into the superclass.
Why does a private subclass field usually become protected after pulling up?
A private field in the superclass is invisible to subclasses, so their existing code would break. Making it protected lets subclasses keep using it. This widens exposure a little, so many teams hide the field behind a protected getter or property instead of allowing direct access.
Should I pull up a field that only two of my five subclasses use?
No. Pulling it up would force the other three subclasses to carry information they never use, which creates the Refused Bequest smell. Pull up only fields that every subclass genuinely shares. When a parent field is used by only some children, apply the inverse refactoring, Push Down Field.
How does Pull Up Field relate to Pull Up Method?
Pull Up Field is usually the first, enabling step. A method cannot move into the superclass while the data it touches still lives in the subclasses. Once the shared field sits in the parent, the duplicated methods that use it can follow with Pull Up Method.

Further reading

Related Lessons