There's an API method to do this:
DataObject newClassInstance( string $newClassName)
Create a new instance of a different class from this object's record.
This is useful when dynamically changing the type of an instance. Specifically, it ensures that the instance of the class is a match for the className of the record. Don't set the DataObject->class or DataObject->ClassName property manually before calling this method, as it will confuse change detection.
If the new class is different to the original class, defaults are populated again because this will only occur automatically on instantiation of a DataObject if there is no record, or the record has no ID. In this case, we do have an ID but we still need to repopulate the defaults.
return The new instance of the new class, The exact type will be of the class name provided.
string $newClassName - The name of the new class
$page = DataObject::get_one('Page'); // a single Page
$newObject = $page->newClassInstance('DataObject');